[英]Likely memory leak in generator loop with islice
我正在處理每個包含數百萬條記錄的大文件(大約2GB解壓縮,幾百MB的gzip)。
我使用islice
迭代記錄,這使得我可以獲得一小部分(用於調試和開發)或者當我想測試代碼時。 我注意到我的代碼的內存使用量非常大,因此我試圖在代碼中找到內存泄漏。
下面是配對讀取中memory_profiler的輸出(我打開兩個文件並壓縮記錄),只有10 ** 5值(默認值被覆蓋)。
Line # Mem usage Increment Line Contents
================================================
137 27.488 MiB 0.000 MiB @profile
138 def paired_read(read1, read2, nbrofitems = 10**8):
139 """ Procedure for reading both sequences and stitching them together """
140 27.488 MiB 0.000 MiB seqFreqs = Counter()
141 27.488 MiB 0.000 MiB linker_str = "~"
142 #for rec1, rec2 in izip(read1, read2):
143 3013.402 MiB 2985.914 MiB for rec1, rec2 in islice(izip(read1, read2), nbrofitems):
144 3013.398 MiB -0.004 MiB rec1 = rec1[9:] # Trim the primer variable sequence
145 3013.398 MiB 0.000 MiB rec2 = rec2[:150].reverse_complement() # Trim the low quality half of the 3' read AND take rev complement
146 #aaSeq = Seq.translate(rec1 + rec2)
147
148 global nseqs
149 3013.398 MiB 0.000 MiB nseqs += 1
150
151 3013.402 MiB 0.004 MiB if filter_seq(rec1, direction=5) and filter_seq(rec2, direction=3):
152 3013.395 MiB -0.008 MiB aakey = str(Seq.translate(rec1)) + linker_str + str(Seq.translate(rec2))
153 3013.395 MiB 0.000 MiB seqFreqs.update({ aakey : 1 })
154
155 3013.402 MiB 0.008 MiB print "========================================"
156 3013.402 MiB 0.000 MiB print "# of total sequences: %d" % nseqs
157 3013.402 MiB 0.000 MiB print "# of filtered sequences: %d" % sum(seqFreqs.values())
158 3013.461 MiB 0.059 MiB print "# of repeated occurances: %d" % (sum(seqFreqs.values()) - len(list(seqFreqs)))
159 3013.461 MiB 0.000 MiB print "# of low-score sequences (<20): %d" % lowQSeq
160 3013.461 MiB 0.000 MiB print "# of sequences with stop codon: %d" % starSeqs
161 3013.461 MiB 0.000 MiB print "========================================"
162 3013.504 MiB 0.043 MiB pprint(seqFreqs.most_common(100), width = 240)
簡而言之,代碼對記錄進行了一些過濾,並跟蹤字符串在文件中出現的次數(在這種特定情況下為壓縮字符串對)。
計數器中100個字符串的150個字符和整數值應該落在100 MB的頂部,我使用@AaronHall的后續函數進行檢查 。
鑒於memory_profiler輸出,我懷疑islice在迭代過程中不會釋放前面的實體。 谷歌搜索讓我看到了這個錯誤報告但是它已被標記為已解決的Python 2.7,這正是我目前正在運行的。
任何意見?
編輯:我已經嘗試按照下面的評論跳過islice
並使用for循環之類的
for rec in list(next(read1) for _ in xrange(10**5)):
這沒有什么顯着差異。 它是在單個文件的情況下,以避免也來自itertools
izip
。
我的第二個故障排除想法是檢查gzip.open()
讀取並將文件擴展到內存,從而導致此問題。 但是,在解壓縮文件上運行腳本沒有任何區別。
請注意,memory_profiler僅報告每行的最大內存消耗。 對於長循環,這可能會產生誤導,因為循環的第一行似乎總是報告不成比例的內存量。
這是因為它將循環的第一行與之前的行的內存消耗進行比較,這將超出循環。 這並不意味着循環的第一行消耗2985Mb,而是循環內存峰值之間的差異比循環外高2985Mb。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.