用tracemalloc跟踪python程序内存占用 这里我们希望能够对比内存映射技术的实际内存占用,因此我们需要引入一个基于python的内存追踪工具:tracemalloc。 我们先看一个简单的案例,创建一个随机数组,观察这个数组的内存占用大小: # tracem.py import tracemalloc import numpy as np tracemalloc.start () length=10000 test_array=np.random.randn(length) # 分配一个定长随机数组 snapshot=tracemalloc.take_snapshot() 接下来做一个简单尝试: # comp_tracem.py import tracemalloc import numpy as np tracemalloc.start() snapshot0=tracemalloc.take_snapshot 总结概要 本文介绍了用tracemalloc来进行python程序的内存追踪的技术,以及简单的文件映射技术mmap的使用方法介绍和演示。
用tracemalloc跟踪python程序内存占用 这里我们希望能够对比内存映射技术的实际内存占用,因此我们需要引入一个基于python的内存追踪工具:tracemalloc。 我们先看一个简单的案例,创建一个随机数组,观察这个数组的内存占用大小: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 # tracem.py import tracemalloc import numpy as np tracemalloc.start() length=10000 test_array=np.random.randn(length) # 分配一个定长随机数组 np tracemalloc.start() snapshot0=tracemalloc.take_snapshot() # 第一张快照 length=10000 test_array=np.random.randn 总结概要 本文介绍了用tracemalloc来进行python程序的内存追踪的技术,以及简单的文件映射技术mmap的使用方法介绍和演示。
内存泄漏例子 import tracemalloc class Foo: def __init__(self): self.arr = list(range(1000000)) self.bar = self tracemalloc.start() # Run your code for i in range(10000): f = Foo() current_mem, peak_mem = tracemalloc.get_traced_memory() print(f"Current memory usage is {current_mem / 10**6}MB") print( f"Peak was {peak_mem / 10**6}MB") tracemalloc.stop() 使用 tracemalloc 跟踪内存使用,程序运行结果: Current memory usage ,可以保护f不被回收 但f.bar也引用了f,形成循环引用,即使外部变量不再引用f,f的内存也无法回收,导致内存泄漏 2. gc.collect 手动回收 使用 gc 模块手动回收垃圾 import tracemalloc
但如果只是要查看单步操作之后的内存变化,tracemalloc的简单易用,让它成为了一个绝佳的选择。本文主要介绍用tracemalloc来追踪代码的内存占用变化。 tracemalloc的使用 tracemalloc的操作逻辑非常简单,在开始统计时使用一个start函数,结束统计的时候使用一个stop函数,中间过程就像拍照片一样不断的使用get_traced_memory import numpy as np import tracemalloc a = np.random.random((1000000,)) tracemalloc.start() current, peak = tracemalloc.get_traced_memory() print(f"Current memory usage is {current / 10**6}MB; Peak was () print(f"Current memory usage is {current / 10**6}MB; Peak was {peak / 10**6}MB") tracemalloc.stop(
tracemalloc模块还使用它们来提供一个了解内存使用情况的窗口。 tracemalloc是在Python 3.4中添加的一个标准库模块,它跟踪Python解释器分配的每个单独的内存块。 tracemalloc能够提供关于运行Python进程中内存分配的非常细粒度的信息: import tracemalloc tracemalloc.start() my_complex_analysis_method MB; Peak was {peak / 10**6}MB") tracemalloc.stop() 调用tracemplugin .start()启动跟踪进程。 tracemalloc将自己深深地注入到正在运行的Python进程中——正如您所预期的那样,这会带来性能损失。在我们的测试中,我们观察到在运行分析时使用tracemalloc的速度下降了30%。 但是,与tracemalloc模块不同的是,资源模块不随时间跟踪使用情况—它只提供点采样。因此,我们需要实现一种方法来随时间对内存使用情况进行采样。
AIAgent││││┌────────┐│││Memory│││└────────┘│││││▼││内存监控器│││││▼││优化策略│└────────────┘四、动态内存监控的实现方案4.1使用tracemalloc 进行精细化追踪Python标准库tracemalloc非常适合用于Agent内存分析。 ()#Agent运行一段时间run_agent_tasks()snapshot2=tracemalloc.take_snapshot()top_stats=snapshot2.compare_to(snapshot1 AgentCallback使用弱引用ThreadPool主动关闭Future长会话周期性快照对比十一、完整示例:带内存监控的Agent主循环展开代码语言:PythonAI代码解释defagent_loop():tracemalloc.start ()snapshot=tracemalloc.take_snapshot()foriinrange(1000):agent.run_step()ifi%100==0:new_snapshot=tracemalloc.take_snapshot
下例将对比定义 __solts__ 和 没有定义 __solts__ 的两个类在创建大量对象时占用的内存大小,其中用了【反射的知识】和 【tracemalloc包】。 tracemalloc包是跟踪由Python分配的内存块的调试工具。 其中: (1)tracemalloc.start()方法表示开始跟踪Python内存分配,开始时内存占用设为1;tracemalloc.stop()表示停止跟踪; (2)tracemalloc.get_traced_memory ()方法能获取由 tracemalloc 模块跟踪的内存块的当前大小和峰值大小作为元组:(current: int, peak: int),单位为字节。 : int) print(tracemalloc.get_traced_memory()) # 停止跟踪 tracemalloc.stop() # 又开始跟踪,相当于重置 tracemalloc.start
如果使用正常的逻辑,那么写出来的程序就是如下所示(关于python内存占用的追踪方法,可以参考这一篇博客): # square_sum.py import tracemalloc import time import numpy as np tracemalloc.start() start_time = time.time() ss_list = np.random.randn(100000) s snapshot.statistics('lineno') for stat in top_stats[:5]: print (stat) 这个程序一方面通过time来测试执行的时间,另一方面利用tracemalloc 如果使用yield的方法,每次只产生一个用于计算的随机数,并且按照上一个章节中的用法,这个迭代生成的随机数也是可以转化为一个完整的list的: # yield_square_sum.py import tracemalloc import time import numpy as np tracemalloc.start() start_time = time.time() def ss_list(length):
self.uid = uid self.name = name self.status = status self.lever = lever import tracemalloc tracemalloc.start() p1 = [Player(1,'zjk') for _ in range(100000)] p2 = [Player2(2,'zs') for _ in range (100000)] snapshot = tracemalloc.take_snapshot() top_stats = snapshot.statistics('lineno') for stat tracemalloc.start() p1 = [Player(1,'zjk') for _ in range(100000)] # p2 = [Player2(2,'zs') for _ in range (100000)] snapshot = tracemalloc.take_snapshot() # top_stats = snapshot.statistics('lineno') top_stats
也是不知道怎么查这种问题,各种百度各种查,也找到了好多推荐的工具,memory_profiler库,objgraph库,graphviz工具,但是都没有帮助我迅速的找到问题点在哪里,最后看到标准库中的tracemalloc ,地址:https://docs.python.org/3/library/tracemalloc.html 通过这个包很快帮我找到了内存泄漏的地方 接下来按照官网的方法我将代码进行改写,来测试到底哪里的问题导致的内存泄漏 ,更改后的服务端代码为: from aiohttp import web import tracemalloc async def hello(request): return web.json_response (await request.json()) async def get_info(request): snapshot2 = tracemalloc.take_snapshot() () snapshot1 = tracemalloc.take_snapshot() web.run_app(app) 注意print(top_stats)这行打印的结果最后要关注 其实这里就是新增加了一个路由
/usr/bin/env python3 # -*- coding: utf8 -*- import timeit import tracemalloc tracemalloc.start() def 记录结束时间和总的耗时情况 start_current, start_peak = tracemalloc.get_traced_memory() start_at = timeit.default_timer end_at = timeit.timeit() cost = timeit.default_timer() - start_at end_current, end_peak = tracemalloc.get_traced_memory /usr/bin/env python3 # -*- coding: utf8 -*- import timeit import tracemalloc tracemalloc.start() def 记录结束时间和总的耗时情况 start_current, start_peak = tracemalloc.get_traced_memory() start_at = timeit.default_timer
针对内存管理,traceMALLOC和traceFREE宏可用于跟踪pvPortMalloc和vPortFree调用,帮助识别未释放的内存块。 在FreeRTOSConfig.h或应用代码中,可以定义以下宏: #define traceMALLOC(pvReturn, xSize) do { \ TaskHandle_t xCurrentTask 例如,若某个地址在traceMALLOC中出现但未在traceFREE中出现,则可能是泄漏点。 通过修改heap_4.c的BlockLink_t结构,添加字段记录分配任务的句柄或名称。
可视化验证 通过tracemalloc模块可以观察内存分配情况: import tracemalloc tracemalloc.start() # 执行代码... snapshot = tracemalloc.take_snapshot() top_stats = snapshot.statistics('lineno') for stat in top_stats
思路二:监测新旧版本内存变化差异 目前python常用的内存检测工具有pympler、objgraph、tracemalloc 等。 另外,研究过程中还发现python3自带了一个内存分析工具tracemalloc,通过如下代码就可以观察代码行与内存之间的关系,虽然可能未必精确,但也能大概提供一些线索。 import tracemalloc tracemalloc.start(25) snapshot = tracemalloc.take\_snapshot() global snapshot gc.collect() snapshot1 = tracemalloc.take\_snapshot() top\_stats = snapshot1.compare\_to(snapshot stats\[:20\]: if stat.size\_diff < 0: continue logger.warning(stat) snapshot = tracemalloc.take
_request(command_info[0], url, body=data) ResourceWarning: Enable tracemalloc to get the object allocation _request(command_info[0], url, body=data) ResourceWarning: Enable tracemalloc to get the object allocation _request(command_info[0], url, body=data) ResourceWarning: Enable tracemalloc to get the object allocation _request(command_info[0], url, body=data) ResourceWarning: Enable tracemalloc to get the object allocation
# 示例代码:使用生成器表达式sum_of_squares = sum(x * x for x in range(10))使用内存分析工具:Python提供了一些内置的内存分析工具,如tracemalloc # 示例代码:使用tracemalloc模块进行内存分析import tracemalloctracemalloc.start()# 执行代码# ...snapshot = tracemalloc.take_snapshot
使用 np.lib.tracemalloc_domain 进行内存跟踪的示例 注意自 Python 3.6(或更新版本)以来,内置的 tracemalloc 模块可以用于跟踪 NumPy 内部的分配。 NumPy 将其 CPU 内存分配放入 np.lib.tracemalloc_domain 域中。 使用np.lib.tracemalloc_domain进行内存跟踪的示例。 请注意,自 Python 3.6(或更新版本)以来,内置的tracemalloc模块可以用于跟踪 NumPy 内的分配。 NumPy 将其 CPU 内存分配放入np.lib.tracemalloc_domain域中。 有关附加信息,请查看:https://docs.python.org/3/library/tracemalloc.html。 这是使用np.lib.tracemalloc_domain的示例。
5.3.1 使用tracemalloc模块tracemalloc是Python标准库中的一个内存跟踪模块,可以帮助我们捕捉和分析程序中内存的使用情况。 memory_intensive_function(): # 模拟一个内存占用大的操作 large_list = [i * i for i in range(1000000)]# 启动内存追踪tracemalloc.start ()# 调用内存密集型函数memory_intensive_function()# 获取当前内存分配情况snapshot = tracemalloc.take_snapshot()top_stats = snapshot.statistics('lineno')# 打印出内存使用情况for stat in top_stats[:10]: print(stat)通过tracemalloc,我们可以监控程序的内存分配情况
self.quantity = quantitydef measure_memory_and_speed(cls, n_objects=1_000_000): # 启动内存跟踪 tracemalloc.start i in range(n_objects)] creation_time = time.time() - start_time # 测量内存 current, peak = tracemalloc.get_traced_memory () tracemalloc.stop() # 测试属性访问速度 start_time = time.time() for obj in objects:
: data = []for p in range(100000):data.append(DataItem("Alex", 42, "middle of nowhere"))snapshot = tracemalloc.take_snapshot