2015-05-28 4 views
7

में लूप के लिए मेमोरी आवंटन मैं एक फ़ंक्शन के लिए पाइथन के स्मृति उपयोग के साथ उलझन में हूं। मैं एक फ़ंक्शन चला रहा हूं जहां एक पांडा डेटाफ्रेम लौटाया जा रहा है (1161 एक्स 240) और तर्क हैं (बामफाइल, पांडा। डेटाफ्रेम (1161 एक्स 50))।पाइथन

अब मैं प्रोफाइलर द्वारा स्मृति के उपयोग दे देंगे:

Line # Mem usage Increment Line Contents 
================================================ 
    120 983.363 MiB 0.000 MiB @profile 
    121        def overlapping_peaks_distribution(bam_peak1, overlap_df): 
    122         ''' 
    123         Returns dataframe for tag count distribution for overlapping peaks within 500bp (+,-) from summit. 
    124         This function also considers the gene transcrition direction. 
    125         :param bam_peak1: 
    126         :param overlap_df: 
    127         :return: 
    128         ''' 
    129 983.363 MiB 0.000 MiB  import pandas as pd 
    130 983.363 MiB 0.000 MiB  import sys 
    131 983.363 MiB 0.000 MiB  peak_distribution_sample = pd.DataFrame() 
    132 983.363 MiB 0.000 MiB  print 'Process: Feature extraction from BAM started' 
    133 1783.645 MiB 800.281 MiB  for ind, row in overlap_df.iterrows(): 
    134 1782.582 MiB -1.062 MiB   sys.stdout.write("\rFeature extraction for peak:%d" % ind) 
    135 1782.582 MiB 0.000 MiB   sys.stdout.flush() 
    136 1782.582 MiB 0.000 MiB   chr = str(row['chr']) 
    137 1782.582 MiB 0.000 MiB   orientation = row['Next transcript strand'] 
    138 1782.582 MiB 0.000 MiB   middle = row['start'] + row['summit'] 
    139 1782.582 MiB 0.000 MiB   start = middle - 3000 
    140 1782.582 MiB 0.000 MiB   stop = start + 50 
    141 1782.582 MiB 0.000 MiB   list_sample1 = [] 
    142          #total_tags = int(bam_peak1.mapped) will get total no of mapped reads 
    143        
    144 1782.586 MiB 0.004 MiB   for i in range(0, 120): 
    145 1782.586 MiB 0.000 MiB    tags1 = bam_peak1.count(chr, start, stop) 
    146 1782.586 MiB 0.000 MiB    start = stop 
    147 1782.586 MiB 0.000 MiB    stop = start + 50 # divide peaks into length of 25 bp 
    148 1782.586 MiB 0.000 MiB    list_sample1.append(tags1) 
    149 1782.586 MiB 0.000 MiB   if orientation > 0: # Direction gene transcription 
    150           #print 'Towards 5 prime' 
    151 1780.883 MiB -1.703 MiB    peak_distribution_sample = peak_distribution_sample.append(pd.Series(list_sample1), ignore_index=True) 
    152          else: 
    153           #print 'Towards 3 prime' 
    154 1783.645 MiB 2.762 MiB    peak_distribution_sample = peak_distribution_sample.append(pd.Series(list_sample1[::-1]), ignore_index=True) 
    155         #print peak_distribution_sample 
    156 1783.645 MiB 0.000 MiB  return peak_distribution_sample 

मुझे समझ में क्यों पंक्ति 133 में यह 800MB (पागल) वृद्धि कर देता है न। यह मेरी याद में सभी जगह खा रहा है। मुझे नहीं पता कि यह मुझसे कुछ गलती है?

मैंने मेमोरी लीक देखने के लिए ऑब्जेक्ट ग्राफ़ का उपयोग किया। समारोह से पहले वस्तु की संख्या शुरू कर दिया:

(Pdb) objgraph.show_most_common_types() 
function     15293 
tuple      4115 
dict      3086 
cell      2670 
list      2107 
weakref     1834 
wrapper_descriptor   1760 
builtin_function_or_method 1655 
getset_descriptor   1235 
type      1232 

वस्तुओं की संख्या के बाद समारोह समाप्त हो गया।

(Pdb) import objgraph 
(Pdb) objgraph.show_growth() 
function      16360  +1067 
dict       3546  +460 
list       2459  +354 
tuple       4414  +306 
getset_descriptor    1508  +273 
builtin_function_or_method  1895  +240 
weakref      2049  +215 
module       593  +123 
wrapper_descriptor    1877  +117 
type       1341  +109 

हम वस्तुओं में उल्लेखनीय वृद्धि देख सकते हैं। मैंने कुछ ग्राफ भी बनाया। enter image description here

मेरा मानना ​​है कि लाल फ़ॉन्ट बॉक्स मुक्त होने के लिए लगता है, लेकिन वे नहीं कर रहे हैं।

+2

यह काफी संभव है कि 'overlap_df.iterrows()' पहले पुनरावृत्ति शुरू करने से पहले स्मृति में पूरी तरह से लोड हो जाता है। – SuperBiasedMan

+0

https://github.com/pydata/pandas/issues/7683 –

+0

यह एक मुद्दा हो सकता है लेकिन उस स्मृति को कैसे मुक्त किया जाए। –

उत्तर

0

क्या आप वाकई overlap_df का कुल आकार नहीं दिखा रहे हैं?

यहाँ अनुरूप चीज नहीं है:

144 1782,586 MiB 0.004 MiB रेंज (0, 120) में मैं के लिए:

प्रोफाइलर 400 KB के रूप में 120 ints की सूची का कुल आकार से पता चलता ।

+0

इसका मतलब है कि ओवरलैप_डीएफ आकार में 800 एमबी है। यह संभव नहीं है क्योंकि भौतिक स्मृति पर यह 8 एमबी की जगह लेता है। मैंने पढ़ा है कि प्रत्येक पुनरावृत्ति के साथ यह स्मृति आवंटित करता है लेकिन इसे जारी नहीं करता है। अंत में फ़ंक्शन आउट_of_memory() प्रिंटिंग के साथ समाप्त होता है। मैंने ** gc.collect() ** भी कोशिश की लेकिन यह प्रभाव नहीं पड़ता है। नेस्टेड लूप इसे और खराब बनाते हैं। –

0

मुझे स्मृति रिसाव मिली है। यह किसी तृतीय पक्ष मॉड्यूल के कारण (pysam) था जिसमें स्मृति रिसाव था।