Yan*_*ann 5 python memory-profiling
我对特定python脚本的内存使用感到非常困惑.尽管有几个SO问题/ 答案的建议,我想我真的不知道如何描述用法.
我的问题是:和之间有什么区别?为什么一个人告诉我我正在使用大量的内存,另一个告诉我我不是?memory_profiler
guppy.hpy
我正在使用pysam
一个用于访问生物信息学SAM/BAM文件的库.当将SAM(ASCII)转换为BAM(二进制)并操纵其间的文件时,我的主脚本会快速耗尽内存.
我创建了一个小测试示例,以了解每一步分配多少内存.
# 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)
Run Code Online (Sandbox Code Playgroud)
使用memory_profiler(python -m memory_profiler test_pysam.py
)监视内存使用情况会产生以下输出:
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
Run Code Online (Sandbox Code Playgroud)
然后注释掉@profile
装饰器并取消注释guppy
相关的行,我得到以下输出(python test_pysam.py
):
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
Run Code Online (Sandbox Code Playgroud)
第13行的总大小在一种情况下为529.03 MB,在另一种情况下为624字节.这里到底发生了什么?'test.sam'是一个~52MB SAM(同样是一种ASCII格式)文件.我深入研究它有点棘手pysam
,因为它是与C库相关的包装器samtools
.无论Samfile
实际是什么,我认为我应该能够了解分配多少内存来创建它.我应该使用什么程序来正确分析更大,更复杂的python程序的每一步的内存使用情况?
memory_profiler和guppy.hpy有什么区别?
您是否了解堆的内部视图与操作系统的外部程序视图之间的区别?(例如,当Python解释器调用free
1MB时,由于多种原因,它不会立即 - 或者甚至永远 - 不会向操作系统返回1MB的页面.)如果这样做,那么答案很简单:memory_profiler是要求操作系统使用你的内存; 孔雀鱼正在从堆结构内部搞清楚它.
除此之外,memory_profiler有一个功能guppy不会自动检测你的功能,在每行代码后打印报告; 它更简单,更容易但灵活性更低.如果你知道你想要做什么而且memory_profiler似乎没有这样做,那么它可能不会; 用孔雀鱼,也许它可以,所以研究文档和来源.
为什么一个人告诉我我正在使用大量的内存,另一个告诉我我不是?
这很难确定,但这里有一些猜测; 答案可能是不止一个的组合:
也许samtools使用mmap将足够小的文件映射到内存中.这会增加页面使用量的大小,但不会增加堆的使用量.
也许samtools或pysam创建了许多可以快速释放的临时对象.你可能有很多碎片(每页只有几个活的PyObjects),或者你的系统的malloc可能已经决定它应该在你的空闲列表中保留很多节点,因为你分配的方式,或者它可能没有返回的页面到操作系统,或操作系统的VM可能没有回收的回收页面.确切的原因几乎总是无法猜测; 最简单的方法是假设永远不会返回释放的内存.
我应该使用什么程序来正确分析更大,更复杂的python程序的每一步的内存使用情况?
如果您从操作系统的角度询问内存使用情况,memory_profiler正在按照您的意愿执行操作.虽然主要挖掘pysam可能很困难,但用@profile
装饰器包装一些函数应该是微不足道的.然后你就会知道哪些C函数负责内存; 如果你想深入挖掘,你显然必须在C级别进行分析(除非有samtools文档或samtools社区中的信息).
归档时间: |
|
查看次数: |
3926 次 |
最近记录: |