使用threading的Python多线程程序因内存溢出被终止,泄漏原因是什么?
Python threading内存泄漏问题分析
核心问题
这段代码的内存泄漏根因是无限制创建非守护线程且未对线程资源进行回收,线程创建速率远大于资源自动释放速率,最终导致内存被耗尽被系统强制终止。
内存泄漏的具体环节
- Python的
threading.Thread创建的默认非守护线程,在线程函数执行完成后,如果没有调用join()方法显式回收,解释器会保留线程的状态数据、返回值等资源不会立即释放 - 主函数是无限循环,每0.5秒就会创建200个执行
f2的子线程,每个f2又会额外创建2个(注:代码中for i in (1,300)是遍历二元组,仅循环2次,若本意是循环1到299需改为range(1,300))执行f1的子线程,所有线程启动后直接丢弃引用,资源持续堆积 - 线程本身的栈空间、内核线程描述符、Python内部的线程对象属性都会占用内存,累积到上限后就会触发系统OOM Killer终止程序
修复方案
- 不要无限制创建线程,优先使用
concurrent.futures.ThreadPoolExecutor线程池控制最大并发数,自动复用线程资源 - 手动管理线程时,需将创建的线程存入列表,待合适时机调用
join()回收 - 无需等待返回的后台线程可以设置
daemon=True,降低不必要的资源留存
修复示例代码
import threading import time from concurrent.futures import ThreadPoolExecutor # 固定最大并发上限,避免资源耗尽 MAX_CONCURRENT = 300 executor = ThreadPoolExecutor(max_workers=MAX_CONCURRENT) def f1(): return def f2(): for i in range(1, 300): executor.submit(f1) return def main(): while True: for i in range(1, 200): executor.submit(f2) time.sleep(0.5) if __name__ == '__main__': main()
内容的提问来源于stack exchange,提问作者Ramesh N
相关产品推荐
相关产品推荐

