tracemalloc分析内存使用情况与泄露方式

 更新时间:2023年11月09日 17:29:26   作者:Bruce小鬼  
这篇文章主要介绍了tracemalloc分析内存使用情况与泄露方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

1.概述

python内存管理是通过引用计数执行的,如果指向某个对象的引用全部过期,那么受引用的对象就可以从内存中清除,从而给其他数据腾出空间。

理论上讲,python开发不用担心程序如何分配和释放内存,因为python系统本身以及Cpython运行环境会自动处理这些问题。

但实际情况程序会因为没有及时释放不再需要引用的数据耗尽内存。下面通过一些方法来看下内存使用情况。

2.查看gc引用对象总数

下面是被测试代码,这个代码可以创建对象,在gc中产生引用对象。

import os

class MyObject:
    def __init__(self):
        self.data = os.urandom(100)

def get_data():
    values = []
    for _ in range(100):
        obj = MyObject()
        values.append(obj)
    return values

def run():
    deep_values = []
    for _ in range(100):
        deep_values.append(get_data())
    return

下面的代码用来输出当前gc引用对象的数量

import gc

# 获取运行前gc引用对象数量
found_objects = gc.get_objects()
print('Before:', len(found_objects))

# 导入待测试模块
import waste_memory

# 运行待测试代码的函数
hold_reference = waste_memory.run()

# 获取运行代码后gc引用对象数量
found_objects = gc.get_objects()
print('After: ', len(found_objects))
for obj in found_objects[:5]:
    print(repr(obj)[:100])

print('...')

运行上面的代码,下面是gc引用的对象总数。

Before: 28834
After:  28923

3.tracemalloc查看内存分配情况

3.1.查看内存分配情况

上面只输出了gc的总数,对于分析内存分配情况没有太多的指导意义,tracemalloc模块能够追溯到分配它的位置,因此我们可以在之前模块前后对内存使用情况做个快照,分析两个快照之间的区别。

下面是被测试代码

import tracemalloc

tracemalloc.start(10)                      # Set stack depth
time1 = tracemalloc.take_snapshot()        # Before snapshot

import waste_memory

x = waste_memory.run()                     # Usage to debug
time2 = tracemalloc.take_snapshot()        # After snapshot

stats = time2.compare_to(time1, 'lineno')  # Compare snapshots
for stat in stats[:3]:
    print(stat)

运行上面的代码,从结果中可以看出,每一条记录都有size与count指标,用来表示这行代码所分配的对象占用多少内存,以及对象的数量。

通过对比就能发现占用内存较多的对象是由那几行代码分配的。

/waste_memory.py:11: size=5120 B (+5120 B), count=80 (+80), average=64 B
/waste_memory.py:14: size=4424 B (+4424 B), count=79 (+79), average=56 B
/waste_memory.py:9: size=1704 B (+1704 B), count=8 (+8), average=213 B

3.2.查看栈信息

tracemalloc还可以打印栈的追踪信息,下面把程序中分配内存最多的那行代码所对应的栈追踪信息打印出来,看看程序是沿着哪条路径触发这行代码的。

import tracemalloc

tracemalloc.start(10)
time1 = tracemalloc.take_snapshot()

import waste_memory

x = waste_memory.run()
time2 = tracemalloc.take_snapshot()

stats = time2.compare_to(time1, 'traceback')
top = stats[0]
print('Biggest offender is:')
# 打印栈信息
print('\n'.join(top.traceback.format()))

运行上面的代码

Biggest offender is:
  File "/with_trace.py", line 14
    x = waste_memory.run()
  File "/waste_memory.py", line 23
    deep_values.append(get_data())
  File "/waste_memory.py", line 16
    obj = MyObject()
  File "/waste_memory.py", line 11
    self.data = os.urandom(100)

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • pytorch 梯度NAN异常值的解决方案

    pytorch 梯度NAN异常值的解决方案

    这篇文章主要介绍了pytorch 梯度NAN异常值的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-06-06
  • Python将列表中的元素转化为数字并排序的示例

    Python将列表中的元素转化为数字并排序的示例

    今天小编就为大家分享一篇Python将列表中的元素转化为数字并排序的示例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-12-12
  • Python打印对象所有属性和值的方法小结

    Python打印对象所有属性和值的方法小结

    在Python开发过程中,调试代码时经常需要查看对象的当前状态,也就是对象的所有属性和对应的值,然而,Python并没有像PHP的print_r那样直接提供一个内置函数来实现这一功能,不过,Python提供了一些工具和方法,可以组合使用来达到打印对象属性和值的目的,下面小编给大家讲讲
    2025-06-06
  • Python基于Streamlit实现音频处理示例详解

    Python基于Streamlit实现音频处理示例详解

    这篇文章主要为大家详细介绍了如何基于Streamlit实现的音频处理,包含录音,语音转文本,文件下载和进度显示功能,有需要的小伙伴可以参考一下
    2025-03-03
  • Python2.7:使用Pyhook模块监听鼠标键盘事件-获取坐标实例

    Python2.7:使用Pyhook模块监听鼠标键盘事件-获取坐标实例

    这篇文章主要介绍了Python2.7:使用Pyhook模块监听鼠标键盘事件-获取坐标实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-03-03
  • Python中对FFmpeg封装开发库FFmpy详解

    Python中对FFmpeg封装开发库FFmpy详解

    这篇文章主要介绍了Python中对FFmpeg封装开发库FFmpy,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-06-06
  • 详解python函数的闭包问题(内部函数与外部函数详述)

    详解python函数的闭包问题(内部函数与外部函数详述)

    这篇文章主要介绍了python函数的闭包问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-05-05
  • 如何利用Python分析出微信朋友男女统计图

    如何利用Python分析出微信朋友男女统计图

    这篇文章主要给大家介绍了关于如何利用Python分析出微信朋友男女统计图的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或工作具有一定的参考学习价值,需要的朋友们下面来一起看看吧
    2019-01-01
  • 在Pandas中使用透视表后去掉多级索引的方法

    在Pandas中使用透视表后去掉多级索引的方法

    Pandas是一个功能强大且通用的Python库,用于数据操作和分析,它最有用的特性之一是数据透视表,它允许您重塑和汇总数据,但是,使用数据透视表通常会导致多级(分层)索引,在本文中,我们将探讨如何在Pandas中使用透视表后去掉多级索引,需要的朋友可以参考下
    2024-12-12
  • Python中pyCirclize包的使用教程详解

    Python中pyCirclize包的使用教程详解

    pyCirclize 是一个 Python 包,用于绘制环形图,这篇文章将将提供更丰富的示例代码,以更全面地展示 pyCirclize 包的功能和用法,感兴趣的小伙伴可以了解一下
    2023-11-11

最新评论