2012-09-21 76 views
5

我對特定python腳本的內存使用情況感到十分困惑。儘管advice來自幾個SO Questions/Answers,但我想我真的不知道如何剖析使用情況。Python中的內存使用情況:memory_profiler和guppy之間有什麼區別?

我的問題是:memory_profilerguppy.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) 

監測與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 

然後註釋掉@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 

第13行的總大小爲529.03 MB在一個案例中另一個是624字節。這裏究竟發生了什麼? 'test.sam'是一個〜52MB的SAM(同樣是一個ASCII格式)文件。對我來說,深入探究pysam有點棘手,因爲它是一個與samtools相關的C庫的封裝。不管實際是什麼,我認爲我應該能夠學習分配多少內存來創建它。我應該使用什麼過程來正確分析我的更大,更復雜的python程序的每一步的內存使用情況?

+0

請注意'test.sam'在第二行,因爲它是一個更長的名稱,一旦我改變它,我意識到我的行號信息將關閉,如果我把文件名放在一行上。 – Yann

回答

7

memory_profiler和guppy.hpy有什麼區別?

您是否理解內部堆視圖與操作系統外部視圖之間的區別? (例如,當Python解釋器在1MB上調用free時,由於多種原因,它不會立即(或甚至可能)返回1MB的頁面到操作系統。)如果這樣做,那麼答案很簡單:memory_profiler要求OS使用內存;孔雀從堆結構內部找出它。

除此之外,memory_profiler有一個功能,guppy不會自動檢測你的函數在每行代碼後打印報表;否則它會更簡單,更簡單但不夠靈活。如果你知道你想要做的事情,而memory_profiler似乎沒有這樣做,它可能不會;與孔布,也許它可以,所以研究文檔和來源。

爲什麼一個人告訴我我正在使用大量的內存,另一個告訴我我不是?

這很難確定,但這裏有一些猜測;答案很可能是多個組合:

也許samtools使用mmap將足夠小的文件映射到內存中。這會使您的頁面使用量增加文件大小,但不會增加您的堆使用率。

也許samtools或pysam會創建很多快速釋放的臨時對象。你可能有很多碎片(每個頁面上只有一對活着的PyObjects),或者你的系統的malloc可能已經決定它應該保留很多節點在它的freelist中,因爲你已經分配了它的方式,或者它可能沒有返回頁面到操作系統,或者操作系統的虛擬機可能沒有回收返回的頁面。確切的原因幾乎總是不可能猜到;最簡單的做法是假定釋放的內存永遠不會返回。

我應該使用什麼程序來正確分析我的更大,更復雜的python程序的每個步驟的內存使用情況?

如果您從操作系統的角度詢問內存使用情況,memory_profiler正在按照您的要求進行操作。雖然主要深入pysam可能很困難,但用裝飾器包裝幾個功能應該是微不足道的。然後你會知道哪些C函數負責內存;如果你想深入挖掘,你顯然必須在C級別進行配置(除非有samtools文檔或samtools社區的信息)。

+0

很好的答案,謝謝。 – Yann

相關問題