首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python中的内存使用: memory_profiler和guppy有什么区别?

Python中的内存使用: memory_profiler和guppy有什么区别?
EN

Stack Overflow用户
提问于 2012-09-21 16:53:46
回答 1查看 4.5K关注 0票数 6

我对特定python脚本的内存使用情况非常困惑。我想,尽管有几个advice问题/Answers,我还是不知道如何描述这个用法。

我的问题是:memory_profiler,,有什么区别?为什么其中一个告诉我我使用了大量的内存,而另一个告诉我我没有?**

我正在使用pysam,一个用于访问生物信息学SAM/BAM文件的库。当将SAM (ASCII)转换为BAM (二进制)并在两者之间操作文件时,我的主脚本很快就会耗尽内存。

我创建了一个小测试示例,以了解每个步骤分配了多少内存。

代码语言:javascript
复制
# test_pysam.py: 

import pysam
#from guppy import hpy

TESTFILENAME = ('/projectnb/scv/yannpaul/MAR_CEJ082/' +
                'test.sam')
#H = hpy()

@profile # for memory_profiler
def samopen(filename):
#    H.setrelheap()
    samf = pysam.Samfile(filename)
#    print H.heap()
    pass


if __name__ == "__main__":
    samopen(TESTFILENAME)

使用memory_profiler (python -m memory_profiler test_pysam.py)监视内存使用情况会产生以下输出:

代码语言:javascript
复制
Filename: test_pysam.py

Line #    Mem usage    Increment   Line Contents
================================================
    10                             @profile # for memory_profiler
    11                             def samopen(filename):
    12     10.48 MB      0.00 MB   #    print H.setrelheap()
    13    539.51 MB    529.03 MB       samf = pysam.Samfile(filename)
    14                             #    print H.heap()
    15    539.51 MB      0.00 MB       pass

然后注释掉@profile装饰符并取消对guppy相关行的注释,得到以下输出(python test_pysam.py):

代码语言:javascript
复制
Partition of a set of 3 objects. Total size = 624 bytes.
 Index  Count   %     Size   % Cumulative  % Kind (class / dict of class)
     0      1  33      448  72       448  72 types.FrameType
     1      1  33       88  14       536  86 __builtin__.weakref
     2      1  33       88  14       624 100 csamtools.Samfile

第13行的总大小在一种情况下是529.03 MB,在另一种情况下是624字节。这到底是怎么回事?'test.sam‘是一个~52 an的SAM (再次是ASCII格式)文件。深入研究pysam有点棘手,因为它是与samtools相关的C库的包装器。不管Samfile实际上是什么,我认为我应该能够了解为创建它分配了多少内存。我应该使用什么过程来正确地描述我更大、更复杂的python程序的每一步的内存使用情况?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-09-21 17:36:44

memory_profiler和guppy.hpy有什么区别?

您是否理解堆的内部视图与操作系统对程序的外部视图之间的区别?(例如,当Python解释器在1MB上调用free时,由于多种原因,它不会立即--甚至可能永远--向操作系统返回1MB的页面。)如果您这样做了,那么答案是非常简单的: memory_profiler要求操作系统使用您的内存;guppy正在从堆结构内部计算它。

除此之外,memory_profiler还有一个特性--自动检测您的函数,以便在每一行代码之后打印报表;除此之外,它更简单、更容易,但灵活性更低。如果您知道有什么您想做的事情,而memory_profiler似乎没有这样做,那么它很可能做不到;使用guppy,也许它可以,所以研究文档和源代码。

为什么其中一个告诉我我使用了大量的内存,而另一个却告诉我我没有?

很难确定,但以下是一些猜测;答案可能是一个以上的组合:

也许samtools使用mmap将足够小的文件完全映射到内存中。这将根据文件的大小增加页面使用量,但根本不会增加堆的使用量。

也许samtools或pysam创建了许多被快速释放的临时对象。您可能会有很多碎片(每个页面上只有几个活动的PyObjects ),或者您的系统的malloc可能已经决定它应该在其自由职业者中保留很多节点,因为您一直在分配,或者它可能还没有将页面返回到操作系统,或者操作系统的VM可能没有返回返回的页面。确切的原因几乎总是无法猜测;最简单的事情就是假设释放的内存永远不会返回。

我应该使用什么过程来正确地描述我更大、更复杂的python程序的每一步的内存使用情况?

如果您从操作系统的角度询问内存使用情况,memory_profiler正在做您想做的事情。虽然对pysam进行深入研究可能很困难,但是使用@profile装饰器包装一些函数应该是很简单的。然后,您将知道哪些C函数负责内存;如果您想深入挖掘,显然必须在C级别进行分析(除非samtools文档中或samtools社区中有信息)。

票数 9
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12534794

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档