我的python应用程序存在问题,我认为这可能与python的垃圾回收有关,尽管我不确定...
问题在于我的应用程序需要很长时间才能退出并切换到下一个功能。
在我的应用程序中,我处理非常大的字典,其中包含数千个大型对象,这些对象是从封装的C++类实例化的。
我在程序中加入了一些时间戳输出,并发现在每个函数结束时,当函数内部创建的对象应该离开作用域时,解释器会花费很多时间,然后才调用下一个函数。在应用程序结束时,我观察到同样的问题:在屏幕上出现最后一个时间戳和新提示出现之间花费了很多时间(约几小时!)。
内存使用稳定,所以我真的没有内存泄漏。
有什么建议吗?
成千上万个大型C++对象的垃圾回收会很慢吗?
有没有方法可以加速它?
更新:
非常感谢你们的所有答案,你们给了我许多调试代码的提示: - )
我在Scientific Linux 5上使用Python 2.6.5,这是一个基于Red Hat Enterprise 5的定制发行版。
实际上,我没有使用SWIG来获取我们C++代码的Python绑定,而是使用了Reflex/PyROOT框架。 我知道,它在粒子物理学之外并不是很知名(但仍然是开源和免费提供的),我必须使用它,因为它是我们主要框架的默认值。
在此背景下,Python端的DEL命令无效,我已经尝试过了。DEL仅删除与C ++对象链接的Python变量,而不是内存中真正拥有该对象的C ++端...
...我知道,这可能不是标准的,并且有点复杂,对此感到抱歉:-P
但是根据你们的提示,我将对我的代码进行分析,并会像你们建议的那样向你们反馈更多详细信息。
附加更新:
好的,按照您的建议,我使用cProfile
在代码中进行了仪器化,并发现实际上gc.collect()
函数是占用运行时间最多的函数!!
这里是cProfile
+ pstats
print_stats()的输出:
>>> p.sort_stats("time").print_stats(20) Wed Oct 20 17:46:02 2010 mainProgram.profile 547303个函数调用(542629个原始调用)共计548.060秒CPU时间
按: 内部时间排序 列表由于限制而从727减少到20
ncalls tottime percall cumtime percall filename:lineno(function) 4 345.701 86.425 345.704 86.426 {gc.collect} 1 167.115 167.115 200.946 200.946 PlotD3PD_v3.2.py:2041(PlotSamplesBranches) 28 12.817 0.458 13.345 0.477 PlotROOTUtils.py:205(SaveItems) 9900 10.425 0.001 10.426 0.001 PlotD3PD_v3.2.py:1973(HistoStyle) 6622 5.188 0.001 5.278 0.001 PlotROOTUtils.py:403(__init__) 57 0.625 0.011 0.625 0.011 {built-in method load} 103 0.625 0.006 0.792 0.008 dbutils.py:41(DeadlockWrap) 14 0.475 0.034 0.475 0.034 {method 'dump' of 'cPickle.Pickler' objects} 6622 0.453 0.000 5.908 0.001 PlotROOTUtils.py:421(CreateCanvas)26455 0.434 0.000 0.508 0.000 /opt/root/lib/ROOT.py:215(__getattr__)
在这段代码中,这是一条记录函数调用的统计信息。该函数名称为"__getattr__",位于"/opt/root/lib/ROOT.py"中的第215行。该函数被调用26455次,它的tottime是0.434秒,percall是0.000秒,cumtime是0.508秒,percall是0.000秒。6622 0.453 0.000 5.908 0.001 /root/svn_co/rbianchi/SoftwareDevelopment
[...] >>>因此,无论是按“时间”还是按“累计”时间排序,gc.collect()
函数都是我程序运行时间消耗最大的函数! :-P这是在返回main()
程序之前进行内存分析的Heapy
输出。在返回之前的内存使用情况: 一组65901个对象的划分。总大小=4765572字节。 索引 数量 % 大小 % 累计占用 % 类型(类/类的字典) 0 25437 39 1452444 30 1452444 30 str 1 6622 10 900592 19 2353036 49 PlotROOTUtils.Canvas字典 2 109 0 567016 12 2920052 61 模块字典 3 7312 11 280644 6 3200696 67 元组 4 6622 10 238392 5 3439088 72 0xa4ab74c 5 6622 10 185416 4 3624504 76 PlotROOTUtils.Canvas 6 2024 3 137632 3 3762136 79 types.CodeType 7 263 0 129080 3 3891216 82 字典(无所有者) 8 254 0 119024 2 4010240 84 类型字典 9 254 0 109728 2 4119968 86 类型 索引 数量 % 大小 % 累计占用 % 类型(类/类的字典)10 1917 3 107352 2 4264012 88 function 11 3647 5 102116 2 4366128 90 ROOT.MethodProxy 12 148 0 80800 2 4446928 92 类的字典 13 1109 2 39924 1 4486852 93 __builtin__.wrapper_descriptor 14 239 0 23136 0 4509988 93 列表 15 87 0 22968 0 4532956 94 guppy.etc.Glue.Interface的字典 16 644 1 20608 0 4553564 94 内建函数类型 17 495 1 19800 0 4573364 94 __builtin__.weakref 18 23 0 11960 0 4585324 95 guppy.etc.Glue.Share的字典 19 367 1 11744 0 4597068 95 __builtin__.method_descriptor你有什么想法,或者怎样优化垃圾回收?
是否还能进行更详细的检查?