performance pycharm内存分析 - 推荐使用哪种Python内存分析器?





memory_profiler使用 python内存监控 (8)


试试pytracemalloc项目 ,它提供了每个Python行号的内存使用情况。

编辑(2014/04):它现在有一个Qt GUI来分析快照。

我想知道我的Python应用程序的内存使用情况,特别想知道哪些代码块/部分或对象消耗了大部分内存。 谷歌搜索显示,商业版本是Python Memory Validator (仅限Windows)。

而开源的是PySizerHeapy

我没有尝试任何人,所以我想知道哪一个是最好的考虑:

  1. 给出大部分细节。

  2. 我必须对我的代码做最少或不做更改。




我建议Dowser 。 这是非常简单的设置,你需要零代码更改。 您可以通过简单的Web界面查看每种类型对象的计数,查看活动对象列表,查看对活动对象的引用。

# memdebug.py

import cherrypy
import dowser

def start(port):
    cherrypy.tree.mount(dowser.Root())
    cherrypy.config.update({
        'environment': 'embedded',
        'server.socket_port': port
    })
    cherrypy.server.quickstart()
    cherrypy.engine.start(blocking=False)

您导入memdebug,并调用memdebug.start。 就这样。

我还没有试过PySizer或Heapy。 我会很感激别人的评论。

UPDATE

以上代码适用于CherryPy 2.XCherryPy 3.Xserver.quickstart方法已被删除,并且engine.start不采用blocking标志。 所以,如果你使用CherryPy 3.X

# memdebug.py

import cherrypy
import dowser

def start(port):
    cherrypy.tree.mount(dowser.Root())
    cherrypy.config.update({
        'environment': 'embedded',
        'server.socket_port': port
    })
    cherrypy.engine.start()



由于没有人提到它,我将指向我的模块memory_profiler ,它能够memory_profiler打印内存使用情况报告,并且可以在Unix和Windows上运行(在最后一个版本上需要使用psutil)。 输出不是非常详细,但目标是让您了解代码消耗更多内存的位置,而不是对分配的对象进行详尽的分析。

在使用@profile装饰你的函数并使用-m memory_profiler标志运行你的代码之后,它将打印一行一行的报告,如下所示:

Line #    Mem usage  Increment   Line Contents
==============================================
     3                           @profile
     4      5.97 MB    0.00 MB   def my_func():
     5     13.61 MB    7.64 MB       a = [1] * (10 ** 6)
     6    166.20 MB  152.59 MB       b = [2] * (2 * 10 ** 7)
     7     13.61 MB -152.59 MB       del b
     8     13.61 MB    0.00 MB       return a



Muppy是另一个Python内存使用情况分析器。 该工具集的重点在于识别内存泄漏。

Muppy试图帮助开发人员识别Python应用程序的内存泄漏。 它可以在运行时跟踪内存使用情况,并识别泄漏的对象。 此外,还提供了一些工具,可以找到未发布对象的来源。




考虑一下objgraph库(有关示例用例,请参阅 )。




我发现meliae比Heapy或PySizer功能更强大。 如果你碰巧正在运行一个wsgi web应用程序,那么Dozer就是一个很好的Dowser中间件包装器




Heapy使用Heapy相当简单。 在代码中的某个时刻,您必须编写以下内容:

from guppy import hpy
h = hpy()
print h.heap()

这给你一些这样的输出:

Partition of a set of 132527 objects. Total size = 8301532 bytes.
Index  Count   %     Size   % Cumulative  % Kind (class / dict of class)
0  35144  27  2140412  26   2140412  26 str
1  38397  29  1309020  16   3449432  42 tuple
2    530   0   739856   9   4189288  50 dict (no owner)

你也可以从对象被引用的地方找出并获得关于这些对象的统计信息,但不知何故文档上的文档有点稀疏。

还有一个图形浏览器,用Tk编写。




阅读本教程后,我尝试将其实现到我的程序中。

我有4-5个包含地址的文件。 每个文件有大约3000万条记录。 我使用的是你建议的相同配置,但我每秒的INSERT数量很低(每秒约10.000条记录)。

这是你的建议失败的地方。 您对所有记录使用单个事务,并且没有错误/失败的单个插入。 假设您将每条记录拆分为不同表上的多个插入。 如果记录坏了会怎么样?

ON CONFLICT命令不适用,因为如果记录中有10个元素,并且需要将每个元素插入到不同的表中,如果元素5出现CONSTRAINT错误,那么之前的所有4个插入也需要。

所以这里是回滚的来源。 回滚的唯一问题是您丢失了所有插入并从顶部开始。 你怎么解决这个问题?

我的解决方案是使用多个交易。 我每隔10.000条记录开始和结束一次交易(不要问为什么这个数字,这是我测试过的最快的数字)。 我创建了一个10.000的数组,并在那里插入成功的记录。 发生错误时,我执行回滚,开始事务,从我的数组中插入记录,提交然后在损坏的记录之后开始新的事务。

这个解决方案帮助我绕过了处理包含错误/重复记录的文件时遇到的问题(我的记录差不多有4%)。

我创建的算法帮助我减少了2个小时的过程。 文件1小时30米的最终加载过程仍然很慢,但与最初的4小时相比没有。 我设法将插入速度从10.000 / s加速到~14.000 / s

如果有人对如何加快它有任何其他想法,我愿意接受建议。

更新

除了上面的答案,你应该记住,每秒插入次数取决于你使用的硬盘驱动器。 我在具有不同硬盘驱动器的3台不同PC上进行了测试,并且在时间上有很大差异。 PC1(1小时30分钟),PC2(6小时)PC3(14小时),所以我开始想知道为什么会这样。

经过两周的研究和检查多个资源:Hard Drive,Ram,Cache,我发现硬盘上的某些设置会影响I / O速率。 通过单击所需输出驱动器上的属性,您可以在常规选项卡中看到两个选项。 Opt1:压缩此驱动器,Opt2:允许此驱动器的文件将内容编入索引。

通过禁用这两个选项,现在所有3台PC都需要大约相同的时间才能完成(1小时和20到40分钟)。 如果遇到慢速插入,请检查您的硬盘驱动器是否配置了这些选项。 它将为您节省大量时间和麻烦,试图找到解决方案





python performance memory-management profiling