gpt4 book ai didi

python - 来自 concurrent.futures 的 RSS 内存使用

转载 作者:太空狗 更新时间:2023-10-29 12:10:34 25 4
gpt4 key购买 nike

我有一个简单的脚本,它试图按如下方式强调 concurrent.futures 库:

#! /usr/bin/python

import psutil
import gc
import os
from concurrent.futures import ThreadPoolExecutor

WORKERS=2**10

def run():
def x(y):
pass

with ThreadPoolExecutor(max_workers=WORKERS) as pool:
for _ in pool.map(x, [i for i in range(WORKERS)]):
pass

if __name__ == '__main__':
print('%d objects' % len(gc.get_objects()))
print('RSS: %s kB' % (psutil.Process(os.getpid()).get_memory_info().rss / 2**10))
run()
print('%d objects' % len(gc.get_objects()))
print('RSS: %s kB' % (psutil.Process(os.getpid()).get_memory_info().rss / 2**10))

这最终会在运行 python 2.7 的 2 核 linux 机器上产生以下输出:

# time ./test.py
7048 objects
RSS: 11968 kB
6749 objects
RSS: 23256 kB

real 0m1.077s
user 0m0.875s
sys 0m0.316s

虽然这是一个有点人为的例子,但我很难理解为什么 RSS 在这种情况下会增加,以及分配的内存用于什么。

Linux 应该使用 COW 很好地处理 fork 内存,但由于 CPython 是引用计数的,因此继承内存的部分不会真正只读,因为需要更新引用。考虑到引用计数的开销是多么小,12MB 的增加让我感到惊讶。如果我不使用 ThreadPoolExecutor 而只是使用 threading 库生成守护线程,RSS 只会增加 4MB。

在这一点上,我绝对不清楚是怀疑 CPython 分配器还是 glibc 分配器,但我的理解是,后者应该可以处理这种并发风格,并且能够重用 arena 来跨生成的线程进行分配。

我在 python 2.7.9 下使用 concurrent.futures 3.0.3 的向后移植版本,在 4.1 内核上使用 glibc 2.4。任何有关如何进一步调查此问题的建议或提示将不胜感激。

最佳答案

大多数内存分配器不会将它们的所有内存返回给操作系统。

尝试调用 run() 两次并在第二次之前/之后检查 RSS。

(也就是说,可笑的线程数量通常不是一个好主意)

关于python - 来自 concurrent.futures 的 RSS 内存使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45946274/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com