Fra*_*rth 164 python debugging memory-leaks memory-management
我有一个长时间运行的脚本,如果让它运行得足够长,将消耗我系统上的所有内存.
没有详细介绍脚本,我有两个问题:
Chr*_*heD 99
看看这篇文章:跟踪python内存泄漏
另请注意,垃圾收集模块实际上可以设置调试标志.看看这个set_debug功能.另外,请查看Gnibbler的此代码,以确定调用后创建的对象类型.
lin*_*nqu 77
我尝试了之前提到的大多数选项,但发现这个小而直观的包是最好的:pympler
跟踪非垃圾收集的对象非常简单,请查看以下小例子:
通过安装包 pip install pympler
from pympler.tracker import SummaryTracker
tracker = SummaryTracker()
# ... some code you want to investigate ...
tracker.print_diff()
Run Code Online (Sandbox Code Playgroud)
输出显示已添加的所有对象以及它们消耗的内存.
样本输出:
types | # objects | total size
====================================== | =========== | ============
list | 1095 | 160.78 KB
str | 1093 | 66.33 KB
int | 120 | 2.81 KB
dict | 3 | 840 B
frame (codename: create_summary) | 1 | 560 B
frame (codename: print_diff) | 1 | 480 B
Run Code Online (Sandbox Code Playgroud)
该软件包提供了许多其他功能.检查pympler的文档,特别是识别内存泄漏一节.
use*_*491 15
Tracemalloc模块作为内置模块集成,从Python 3.4开始,显然,它也可用于以前版本的Python作为第三方库(尽管尚未测试).
该模块能够输出分配最多内存的精确文件和行.恕我直言,这些信息无疑比每种类型的分配实例的数量更有价值(99%的时间最终会成为很多元组,这是一个线索,但在大多数情况下几乎没有帮助).
我建议你将tracemalloc与pyrasite结合使用.10次中的9次,在pyrasite-shell中运行前10个片段将为您提供足够的信息和提示,以便在10分钟内修复泄漏.然而,如果您仍然无法找到泄漏原因,pyrasite-shell与此线程中提到的其他工具相结合可能会给您更多提示.您还应该查看pyrasite提供的所有额外帮助程序(例如内存查看器).
Jue*_*gen 11
您应该专门查看全局或静态数据(长寿命数据).
当这些数据不受限制地增长时,您也可能在Python中遇到麻烦.
垃圾收集器只能收集不再引用的数据.但是您的静态数据可以连接应该释放的数据元素.
另一个问题可能是内存周期,但至少从理论上讲,垃圾收集器应该找到并消除周期 - 至少只要它们没有挂在一些长期的生存数据上.
什么样的长寿数据特别麻烦?仔细查看任何列表和词典 - 它们可以不受限制地增长.在字典中,您甚至可能看不到麻烦,因为当您访问dicts时,字典中的键数可能对您来说不是很大的可见性......
至于最佳实践,请留意递归函数。就我而言,我遇到了递归问题(不需要的地方)。我在做什么的一个简化示例:
def my_function():
# lots of memory intensive operations
# like operating on images or huge dictionaries and lists
.....
my_flag = True
if my_flag: # restart the function if a certain flag is true
my_function()
def main():
my_function()
Run Code Online (Sandbox Code Playgroud)
以这种递归方式操作不会触发垃圾收集并清除函数的剩余部分,因此每次通过内存使用量都在增长。
我的解决方案是将递归调用从 my_function() 中提取出来,并让 main() 处理何时再次调用它。这样函数自然结束并自行清理。
def my_function():
# lots of memory intensive operations
# like operating on images or huge dictionaries and lists
.....
my_flag = True
.....
return my_flag
def main():
result = my_function()
if result:
my_function()
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
131919 次 |
| 最近记录: |