我试图在一个使用tracemalloc提取代码帧的大型项目中查找内存泄漏。但是,我不能获得多个最深的框架,对于具有大量依赖项和无数嵌套调用的大型项目来说,这是无用的。根据医生们的说法,我试图使用:
tracemalloc.start极限参数PYTHONTRACEMALLOC env变量-X tracemalloc命令行参数tracemalloc.get_traceback_limit()显示了我设置的正确数字。然而,每个回溯对象我仍然只能得到一个帧。在不同的机器上,Python版本3.8.5和3.9.7的工作原理是相同的。这里怎么了??我怎么才能解决这个问题?
下面是最小的例子:
import os
import tracemalloc
def get_top_malloc(trace_number):
snapshot = tracemalloc.take_snapshot()
snapshot = snapshot.filter_traces((
tracemalloc.Filter(False, "<frozen importlib._bootstrap>"),
tracemalloc.Filter(False, "<unknown>"),
))
top_stats = snapshot.statistics("lineno")
msg = []
if trace_number > 0:
msg.append(f"Top malloc {trace_number} lines")
for index, stat in enumerate(top_stats[:trace_number]):
msg.append(f"#{index}: {stat.size // 1024} KB, {stat.count} times")
print(stat.traceback._frames) # Only single frame is here!
print(dir(stat.traceback))
msg.extend(line for line in stat.traceback.format(limit=16))
other = top_stats[trace_number:]
if other:
size = sum(stat.size for stat in other)
msg.append(f"{len(other)} other: {size // 1024} KB")
total = sum(stat.size for stat in top_stats)
msg.append(f"Total allocated size: {total // 1024 // 1024} MB")
return "\n".join(msg)
storage = {}
def func2():
def func3():
value = '3.1415926535897932384626433832795028841971'
value = value * 4096
storage['pi'] = value
func3()
def func1():
func2()
if __name__ == "__main__":
tracemalloc.start(4)
print(f"\n-- Limit: {tracemalloc.get_traceback_limit()}")
func1()
print(f"\n-- {get_top_malloc(1)}")
tracemalloc.stop()发布于 2021-12-02 09:08:15
我已经找到了解决方案,它是微不足道的,但并不明显。快照对象的statistics(...)方法采用一个key_type参数,用于按文件("filename")、file+line ("lineno")或整体跟踪("traceback")对跟踪进行分组。我使用了默认值"lineno",它过滤掉了不包括每个回溯的最后一个帧的所有内容,因此切换到"traceback"选项解决了这个问题,并允许我获得所需的所有帧( :) )。
https://stackoverflow.com/questions/70182033
复制相似问题