PyPy的内存使用量随时间增加

3
我注意到我的程序在PyPy和Python下的内存使用存在一些奇怪的问题。在PyPy下,程序不仅使用了比CPython更多的初始内存,而且随着时间的推移,内存使用量会急剧增加。在PyPy下,程序在结束时使用约170MB的内存,而在CPython下运行时仅使用14MB。
我发现一个用户遇到了完全相同的问题,尽管规模较小,但对他有效的解决方案对我的程序只有一点帮助 pypy memory usage grows forever?。我尝试了两件事情:将环境变量PYPY_GC_MAX设置为100MB和PYPY_GC_GROWTH=1.1,并在每个代中手动调用gc.collect()。
我使用以下代码确定内存使用情况:
resource.getrusage(resource.RUSAGE_SELF).ru_maxrss/1000

这是在不同条件下运行时和内存使用情况:
Version: time taken, memory used at end of run
PyPy 2.5.0: 100s, 173MB
PyPy with PYPY_GC_MAX = 100MB and PYPY_GC_GROWTH = 1.1: 102s, 178MB
PyPy with gc.collect(): 108s, 131MB
Python 2.7.3: 167s, 14MB

正如您所看到的,PyPy比CPython更快,这就是我一开始转换的原因,但代价是内存增加了10倍。
这个程序是基因编程的实现,我正在演变一个算术二叉树,经过100代,人口数量为200。树中的每个节点都有对其两个子节点的引用,这些树的大小可以增加,尽管对于这个实验它们保持相对稳定。根据应用程序,该程序可以运行10分钟到几个小时,但对于这里的结果,我将其设置为较小的数据集以突出显示问题。
是否有任何人知道a)可能是什么原因,b)是否可能将内存使用限制在比较可接受的水平?

运行 gc.collect 对我来说会增加内存使用量。而且CPython比PyPy使用更多的内存。奇怪。 - noɥʇʎԀʎzɐɹƆ
1个回答

9
PyPy使用的基准内存比CPython更多,而且随着JIT编译越来越多的机器代码,这个数字会随时间增加。它会(或者至少应该)收敛 --- 这意味着内存使用量应该随着程序运行而增加,但只增加到一个最大值。在运行10分钟或几个小时后,您应该得到大致相同的使用情况。
我们可以无休止地讨论170MB是否对于“基准”来说太多了。我可以告诉您的是,在CPython上使用几GB内存的程序在PyPy上使用的内存不会显著增加 --- 这是我们的目标和迄今为止的经验;但是如果您的经验有所不同,请将其报告为错误。

我观察到我的程序存在的问题是,内存使用似乎没有收敛。在正常情况下,我在同一进程中连续运行程序10次。我刚刚测试了一下,PyPy在结束时使用了500MB,而Python仍然使用14MB。我用PyPy进行科学研究,我运行程序的计算机如果使用超过1GB就会终止它们,这已经发生了几次。我可以将程序作为单独的进程运行10个实验,但是JIT warm up的时间就不够长了。我会尝试更多地调整GC选项。 - Stuart Lacy
2
我们(PyPy团队)总是准备更深入地研究这类问题。欢迎报告问题,例如在http://bugs.pypy.org/上或与我们在irc.freenode.net的#pypy聊天中讨论。 - Armin Rigo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接