- 主题:请教个内存占用的问题
我有段代码,逻辑总结起来比较简单:
@functools.cache
def a_long_time_calc(cis):
...
for n in (...):
cis = tuple(some_dic.keys())
# cis 有较不小概率是会重复的
calc_res = a_long_time_calc(cis)
another_long_time_proc(...)
...
因为for n 循环跑的次数比较多, 而且cis本身也不短,导致随程序运行,内存占用会越来越多,然后被系统杀死,用memory_profiler做prof看的结果就是cis = tuple(...)这里不停的占用内存,要命的地方是, some_dic是从数据库里根据n实时抓出来的,他的keys没有办法做成预定义的。在运行一段时间之后主动调用gc.collect也没有效果。
请教一下, 有没有办法在运行一段时间之后把cis这个内存释放掉啊。
--
FROM 221.224.37.*
估计是有内存泄漏,只不过最后刚好在那里爆掉
【 在 pcal 的大作中提到: 】
: 我有段代码,逻辑总结起来比较简单:
: @functools.cache
: def a_long_time_calc(cis):
: ...................
--
FROM 124.127.177.*
我换了个2T内存的机器把程序完整跑了一遍prof, memory在cis = tuple(...)那边增加比较多,其他地方微乎其微。
【 在 kawolu 的大作中提到: 】
: 估计是有内存泄漏,只不过最后刚好在那里爆掉
:
--
FROM 221.224.37.*
逻辑允许的话,用生成器呗
【 在 pcal 的大作中提到: 】
: 我换了个2T内存的机器把程序完整跑了一遍prof, memory在cis = tuple(...)那边增加比较多,其他地方微乎其微。
--
FROM 61.149.73.110
生成器没法cache, a_long_time_calc非常耗时
【 在 annals 的大作中提到: 】
: 逻辑允许的话,用生成器呗
:
--
FROM 221.224.37.*
我遇到过这样的问题,后面都解决了,方法无外乎两种:
1. cis没有被释放,是因为cis里有的对象被使用并保存了,导致cis不会被释放,比如其它
地方有类似于`a_global_list.append(cis[0])`这样的代码。这个得你自己查。
2. 实在查不出问题了,重设计代码,改为多进程,有内存泄露问题的代码放到子进程里运行,子进程退出时内存会被操作系统回收。
【 在 pcal 的大作中提到: 】
: 我有段代码,逻辑总结起来比较简单:
: @functools.cache
: def a_long_time_calc(cis):
: ...................
--
FROM 116.237.207.*
改用@functools.lru_cache试试
至少可以设一下maxsize
【 在 pcal 的大作中提到: 】
: 我有段代码,逻辑总结起来比较简单:
: @functools.cache
: def a_long_time_calc(cis):
: ...................
--
FROM 123.123.203.*
查过了, 就是a_long_time_calc会用, 我也试过不用functools.cache, 自己维护一个cache,因为cache有几乎一半的概率会被命中,按道理来说循环结束后会把多次命中的key释放掉,但也没有。
我现在再想对数据库的数据做个预处理行不行,比如再存个本地数据库比如ZODB之类,把cis存到数据库里,利用持久化共享的特性来减少重复cis的内存占用。
【 在 RunningOn 的大作中提到: 】
: 我遇到过这样的问题,后面都解决了,方法无外乎两种:
: 1. cis没有被释放,是因为cis里有的对象被使用并保存了,导致cis不会被释放,比如其它
: 地方有类似于`a_global_list.append(cis[0])`这样的代码。这个得你自己查。
: ...................
--
FROM 221.224.37.*
some_dic是个不随外部for循环变化的静态字典么?是的话没有必要每次都生成一个tuple?不是的话,每次some_dic的key都不一样,functools.cache作用大么?
如果因为某些原因,some_dic在每次循环中都会变,而且不需要对keys排序,而且functools.cache的命中率还非常高,可以考虑用外部缓存,比如文件系统,sqlite等。但是这些“而且”都成立的情形很奇怪啊。。。
【 在 pcal 的大作中提到: 】
: 我有段代码,逻辑总结起来比较简单:
: @functools.cache
: def a_long_time_calc(cis):
: ...................
--
FROM 111.196.23.*
@functools.cache
def a_long_time_calc(cis):
...
for n in (...):
cis = tuple(some_dic.keys())
# cis 有较不小概率是会重复的
calc_res = a_long_time_calc(cis)
cis = tuple() #增加这一句?
another_long_time_proc(...)
...
【 在 pcal 的大作中提到: 】
: 我有段代码,逻辑总结起来比较简单:
: @functools.cache
: def a_long_time_calc(cis):
: ...................
--
FROM 111.46.9.*