【问题标题】:Measuring the allocated memory with tracemalloc使用 tracemalloc 测量分配的内存
【发布时间】:2021-12-29 22:25:00
【问题描述】:

Python 模块tracemalloc 提供了对程序分配内存的详细了解。例如,一个用例是记录当前和峰值内存使用情况:

import tracemalloc

tracemalloc.start()

# ...code...

current, peak = tracemalloc.get_traced_memory()

如果我们现在想要重置峰值,文档建议使用tracemalloc.reset_peak()。不过这个功能是Python 3.9才加入的,不知道用tracemalloc.clear_traces()能不能达到同样的效果?

我的用例是这样的:

for i in range(10): 
     # do sth
     current, peak = tracemalloc.get_traced_memory()
     print('Current and peak memory usage: {} {}'.format(current, peak))
     # clear peak memory 

所以对于for循环中的每个i,我都会做某事并且只想测量我创建的内存。峰值应该只针对每个索引,而不是针对全局运行,这就是我要清除它的原因。

编辑:为了测试reset_peak()clear_traces() 之间的区别,我测试了这个程序:

tracemalloc.start()
current_memories = []
peak_memories = []
for i in range(10): 
    a = list(range(100000))
    current, peak = tracemalloc.get_traced_memory()
    current_memories.append(current/(1024*1024))
    peak_memories.append(peak/(1024*1024))
    tracemalloc.reset_peak()
    # tracemalloc.clear_traces()
    del current, peak
print('Average current memory [MB]: {}, average peak memory [MB]: {} +/- {}'.format(
      round(np.mean(current_memories), 4), round(np.mean(peak_memories), 4), 
      round(np.std(peak_memories), 4))
)

当我测试clear_traces()时,输出是:

Average current memory [MB]: 3.4273, average peak memory [MB]: 3.4274 +/- 0.0019

当我改为使用reset_peak() 时,我得到:

Average current memory [MB]: 3.4313, average peak memory [MB]: 6.5156 +/- 1.0273

为什么这两种方法在显示的内存量上存在差异?

【问题讨论】:

  • 你为什么要问我们?你有没有测试过它自己是否有效?
  • 所以,你只需要记住你得到的最后一个值,然后从新值中减去它。你不需要清除任何东西。
  • @TimRoberts 不确定我能不能跟上。毕竟,如果我做了两件事,第二个操作的内存消耗会比第一个操作少很多,那么peak 仍然会有第一个操作的内存消耗,对吧?

标签: python tracemalloc


【解决方案1】:

在python3.9之前模仿reset_peak似乎是不可能的。 reset_peak是一个C函数,代码为peak = current,内存计数器是C变量,所以不能在python中修改。

使用 clear_traces 会忘记所有以前的分配:

>>> import tracemalloc
>>> tracemalloc.start()
>>> a = list(range(1000))
>>> tracemalloc.get_traced_memory()
(37619, 47929)
>>> tracemalloc.clear_traces()
>>> tracemalloc.get_traced_memory()
(8691, 19001)

【讨论】:

  • 我有一个简短的后续问题:“所有以前的分配都被遗忘”到底是什么意思?因为从你的例子来看,在我看来我们可以使用tracemalloc.clear_traces() 而不是tracemalloc.reset_peak(),不是吗?
  • clear_traces 将当前设置为 0。在此之后,只会计算新的分配。
  • 在您提供的示例中,current 不是 0,不是吗?
  • 当一个人调用tracemalloc.clear_traces() 时,peak 会发生什么?
  • 可能是tracemalloc的一些内部分配。
猜你喜欢
  • 1970-01-01
  • 2018-08-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-27
相关资源
最近更新 更多