- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在开发一个主要是 API 的应用程序,但也有一个多线程后台作业处理系统,用于执行计划作业以及即时 API 响应时间过长的临时作业。
这将通过gunicorn fork 10次。任何单个 fork 进程都能够获取要运行的作业,因此作业处理在进程之间与 API 请求服务之间保持平衡。
我的挑战是每个进程如何继续获取作业处理所需的峰值内存量。有些作业需要 1.5GB-2GB 的内存。
如果有足够的时间,最终所有 10 个进程都必须完成这些类型的工作,并且每个进程都将占用 2GB 以上的内存。即使进程的平均内存使用很少超过 100MB。
这些密集型作业仅通过进程内的专用线程运行。
是否有任何机制可以强制Python在线程关闭时释放专门为该线程声明的内存?或者有什么通用机制可以强制 Python 进程将内存重置为当时真正需要的内存?
旁注:我也在探索 fork 而不是线程,但到目前为止,这引入了其他问题,我不确定我是否可以解决。
最佳答案
为了证明线程在其工作完成后被销毁,您可以运行以下代码:
def job(o: dict):
count = 1
r = random.randrange(10, 20)
while count < r:
print(f"{o['name']}={count}/{r}")
count += 1
time.sleep(1)
print(f"{o['name']} finished.")
def run_thread(o: dict):
threading.Thread(target=job, args=(o,)).start()
if __name__ == '__main__':
obj1 = {"name": "A"}
run_thread(obj1)
obj2 = {"name": "B"}
run_thread(obj2)
while True:
time.sleep(1)
print(f"THREADS: {len(threading.enumerate())}")
输出将是这样的:
A=1/14
B=1/10
THREADS: 3
B=2/10
A=2/14
THREADS: 3
...
B finished.
A=10/14
A=11/14
THREADS: 2
A=12/14
THREADS: 2
A=13/14
THREADS: 2
A finished.
THREADS: 1
THREADS: 1
THREADS: 1
正如您所看到的,每当线程结束时,总线程数就会减少。
更新:
好的。我希望这个脚本能让您满意。
from typing import List
import random
import threading
import time
import os
import psutil
def get_mem_usage():
return PROCESS.memory_info().rss // 1024
def show_mem_usage():
global MAX_MEMORY
while True:
mem = get_mem_usage()
print(f"Currently used memory={mem} KB")
MAX_MEMORY = max(mem, MAX_MEMORY)
time.sleep(5)
def job(name: str):
print(f"{name} started.")
job_memory: List[int] = []
total_bit_length = 0
while command['stop_thread'] is False:
num = random.randrange(100000, 999999)
job_memory.append(num)
total_bit_length += int.bit_length(num)
time.sleep(0.0000001)
if len(job_memory) % 100000 == 0:
print(f"{name} Memory={total_bit_length//1024} KB")
print(f"{name} finished.")
def start_thread(name: str):
threading.Thread(target=job, args=(name,), daemon=True).start()
if __name__ == '__main__':
command = {'stop_thread': False}
STOP_THREAD = False
PROCESS = psutil.Process(os.getpid())
mem_before_threads = get_mem_usage()
MAX_MEMORY = 0
print(f"Starting memory={mem_before_threads} KB")
threading.Thread(target=show_mem_usage, daemon=True).start()
input("Press enter to START threads...\n")
for i in range(20):
start_thread("Job" + str(i + 1))
input("Press enter to STOP threads...\n")
print("Stopping threads...")
command['stop_thread'] = True
time.sleep(2) # give some time to stop threads
print("Threads stopped.")
mem_after_threads = get_mem_usage()
print(f"Memory before threads={mem_before_threads} KB")
print(f"Max Memory while threads running={MAX_MEMORY} KB")
print(f"Memory after threads stopped={mem_after_threads} KB")
input("Press enter to exit.")
这是输出:
Starting memory=12980 KB
Currently used memory=13020 KB
Press enter to START threads...
Job1 started.
Job2 started.
Job3 started.
Job4 started.
Job5 started.
Job6 started.
Job7 started.
Job8 started.
Job9 started.
Job10 started.
Job11 started.
Job12 started.
Job13 started.
Job14 started.
Job15 started.
Job16 started.
Job17 started.
Job18 started.
Job19 started.
Job20 started.
Press enter to STOP threads...
Currently used memory=16740 KB
Currently used memory=19764 KB
Currently used memory=22516 KB
Currently used memory=25420 KB
Currently used memory=28340 KB
Stopping threads...
Job12 finished.
Job20 finished.
Job11 finished.
Job7 finished.
Job18 finished.
Job2 finished.
Job4 finished.
Job19 finished.
Job16 finished.
Job10 finished.
Job1 finished.
Job9 finished.
Job6 finished.
Job13 finished.
Job15 finished.
Job17 finished.
Job3 finished.
Job5 finished.
Job8 finished.
Job14 finished.
Threads stopped.
Memory before threads=12980 KB
Max Memory while threads running=28340 KB
Memory after threads stopped=13384 KB
Press enter to exit.
Currently used memory=13388 KB
我真的不知道为什么会有 408 KB 的差异,这可能是使用 15 MB 内存的开销。
关于python - 线程结束后释放内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50031691/
我有一个附加了 View Controller 的 AVAudioPlayer 实例。 @property (nonatomic, retain) AVAudioPlayer *previewAudi
我是java初学者。假设我声明了一个 Account 类型的变量 Account _account = new Account("Thomas"); 然后在其他地方我做了这样的事情: _account
我在我的应用程序中使用了 3 个 UIViewController,现在我想知道当我从另一个应用程序切换到另一个 UIViewController 时释放它们是否是一个好主意。显然,这将是隐藏的,当它
我分配了一个直接缓冲区: ByteBuffer directBuffer = ByteBuffer.allocateDirect(1024); 我读过: Deallocating Direct Buf
场景。我有一个图表,我可以使用右键单击来执行平移。这非常有效。然后我完美地添加了右键菜单。 问题。现在,即使在拖动操作完成后释放鼠标,也会显示右键菜单。 有没有办法在 Java Swing 或 Jav
我使用此代码获取 ABPerson 的姓氏 CFStringRef lastNameRef = ABRecordCopyValue((ABRecordRef)personRecordRef, kABP
目前,我们在基于 C 的嵌入式应用程序中使用 malloc/free Linux 命令进行内存分配/取消分配。我听说这会导致内存碎片,因为内存分配/取消分配会导致堆大小增加/减少,从而导致性能下降。其
当我尝试释放缓冲区时遇到问题。每次我尝试将缓冲区传递给释放方法时,都会发生段错误。 Valgrind 确认段错误位于 BufferDeallocate 方法中。 ==30960== Memcheck,
我想知道何时按下或释放修改后的键(Ctrl 或 Shift)。 基本上,用户可以在按下修改键的情况下执行多次击键,而我不想在它被释放之前执行一个操作(想想 Emacs 和 Ctrl + X + S).
我编写了一个相当大的网络应用程序。它运行良好一段时间,然后慢慢开始运行缓慢,因为 DOM 节点开始爬升到 80,000 - 100,000 左右。 所以我一直在 Chrome 开发工具控制台 (DCT
我知道在像 c 这样的语言中,我需要在分配内存后释放它。 (我来自 Java),对此我有几个问题: 当我在做的时候: int array[30]; (即创建一个大小为 30 个整数的数组)与
这个问题在这里已经有了答案: 关闭 11 年前。 Possible Duplicate: How to release pointer from boost::shared_ptr? Detach
我有一个可以从多个后台线程访问的类,可能同时访问。我无法复制该类,因为重新创建它的内容(处理或内存方面)可能很昂贵。 也有可能在后台处理仍在继续并访问该属性时替换了此类的属性。 目前我有定期的保留/释
这个问题是对: 的扩展链接-1:Creating an image out of the ios surface and saving it Link-2:Taking Screenshots fro
我有一个实例变量 NSMutableArray* searchResults。 首先,我初始化它: self.searchResults = [[NSMutableArray alloc] init]
如果我在堆上声明一些东西,比如 char *a=new char[1000] 并且主程序停止,如果没有 delete[]<,那么分配的内存会发生什么 调用?它保留在堆上还是自动释放? 最佳答案 就C+
在开发相机应用时,我遇到了一个异常,该异常仅在我切换到其他应用时发生(onPause() 用于我的应用)。 01-15 17:22:15.017: E/AndroidRuntime(14336): F
使用 JDK 1.8 编译时出现 maven 编译器错误 无法执行目标 org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (de
将 BufferedImage 保存到磁盘(以释放内存)的最快方法是什么? 我的 Java 应用程序处理大量图像(每约 300 毫秒将图像加载到内存中)。大多数这些图像都会立即被丢弃 (gc),但每隔
使用 JDK 1.8 编译时出现 maven 编译器错误 未能在项目 DUMMY 上执行目标 org.apache.maven.plugins:maven-compiler-plugin:3.8.1:
我是一名优秀的程序员,十分优秀!