2015-12-29 30 views
-2

我遇到了Python中的內存管理問題,我不明白,我會歡迎任何有關此問題的反饋。幾個月來我一直沒有任何編程背景給自己學習,我似乎偶然發現了GC的一些基本問題,但我無法理解根本原因。主要問題之外的任何意見也是受歡迎的。 注:主要的問題點2處開始,其餘爲背景/支撐)爲什麼使用函數參數的副本的行爲與GC的函數參數不同?

主程序是下述(然後我將列出步驟):

import aggregateData 
import breakToTimeIntervals 

START_LINE = 1000 # Defines the starting point in the raw forex data file 
INTERVALS = [5, 10, 15, 20, 30, 60, 240, 1440] # Time intervals of interest 
FIELDS = ['Date', 'Time', 'Open', 'High', 'Low', 'Close'] 

<some functions> 

if __name__ == '__main__': 
    checkData = aggregateData.main() 
    if checkData[0] == True: 
     logger.info("Data was already aggregated") 
    else: 
     logger.info("New data aggregation was performed") 
     subdivideData= breakToTimeIntervals.main(checkData[1], INTERVALS, 
      START_LINE, FIELDS) 
     logger.info("Subdivision completed. Intervals: " + str(INTERVALS)) 

1)aggregateData :我有一個可以添加多個外匯數據CSV的目錄。外匯數據出現在一年的區塊內;該程序的第一件事是檢查是否有一個名爲(COMPILED_FILE_NAME)的文件,如果沒有,它會將預期目錄中的所有文件編譯爲名爲COMPILED_FILE_NAME的單個CSV文件。我需要知道它是否編譯了一個新文件,因爲那樣我必須通過步驟2來細分數據;因此布爾輸出。所有文件在最後關閉,到目前爲止沒有內存泄漏。

DIRECTORY = 'rawData/' 
COMPILED_FILE_NAME = 'Combined_data.csv' 
FILES = [f for f in listdir(DIRECTORY) if isfile(join(DIRECTORY, f)) and 
     f != COMPILED_FILE_NAME] 

<some functions> 

def main(): 
    bool_aggregated = False 
    if not os.path.isfile(DIRECTORY + COMPILED_FILE_NAME): 
     logger.info('Aggregating raw data for: %s' % FILES) 
     load = load_individual_file(DIRECTORY + FILES[0]) 
     for x in range(len(FILES)-1): 
     addition = load_individual_file(DIRECTORY + FILES[x+1]) 
     compiled = aggregate(load, addition) 
     load = [] # Note I thought the memory leak might come here somehow, so added this 
     load = compiled[:] 
     output = write_output(compiled, (DIRECTORY + COMPILED_FILE_NAME)) 
    else: 
     compiled = load_individual_file(DIRECTORY + COMPILED_FILE_NAME) 
     logger.info('Data already aggregated for: %s' % FILES) 
     bool_aggregated = True 
    return bool_aggregated, compiled 

if __name__ == '__main__': 
    main() 

2)breakToTimeIntervals:這是我得到3演出內存泄漏,這取決於予是否使用()傳遞給主參數或它的一個副本。這工作:

<some functions> 

def write_outputs(divided_data, intervals, column_titles): 
    for x in range(len(divided_data)): 
     f = open(OUTPUT_DIR + str(intervals[x]) + "_min.csv", 'w') 
     f.write(','.join(map(str, column_titles))) 
     f.write('\n') 
     for y in range(len(divided_data[x])): 
     to_write = divided_data[x][y] 
     f.write(','.join(map(str,to_write))) 
     f.write("\n") 
     f.close() 
    return None 

def main(raw_data, requested_time_intervals, start_line, col_titles): 
    getStartLine = find_nearest_whole_hour(raw_data, start_line) 
    breakIntoSubdivisions = subdivide_into_intervals(getStartLine, raw_data, 
     requested_time_intervals) 
    COLUMNS = col_titles 
    writeOutputs = write_outputs(breakIntoSubdivisions, 
     requested_time_intervals, COLUMNS) 
    return None 

但在節目結束後,這個豬的記憶:

def write_outputs <AS ABOVE> 

然後

def main(raw_data, requested_time_intervals, start_line, col_titles): 
    getStartLine = find_nearest_whole_hour(raw_data, start_line) 
    breakIntoSubdivisions = subdivide_into_intervals(getStartLine, raw_data, 
     requested_time_intervals) 
    writeOutputs = write_outputs(breakIntoSubdivisions, 
     requested_time_intervals, col_titles) 
    return None 

對不起,長職位,但我認爲糖化在一起位,我學過谷歌可能會讓我建立一個容易失敗的系統。

+1

有**無**差的代碼這兩個比特之間。你甚至沒有製作第一個col_titles的副本,只是分配一個額外的名字。沒有可能的方式,一個變化可能導致內存泄漏;你的問題在別處。 –

+0

@DanielRoseman這是讓我困惑的部分。我已經跑了20多次,結果總是一樣的;現在我想這可能是由於我用Enthought Canopy來運行代碼?奇怪的是 – roganjosh

+0

。給col_titles添加一個額外的引用不應該對GC產生影響。直到腳本退出爲止,它將不會被GC'ed,因爲它綁定到全局'FIELDS'列表。請嘗試製作一個再現此問題的[mcve]。 –

回答

1

你的問題很混亂,你可能想編輯它。爲什麼有3個main()函數?第一個代碼(你稱之爲「主程序」)似乎與執行的其餘部分(可能更好地指定時間軸?)完全吻合。

我現在唯一能注意到的是,你打開了很多文件,並沒有在函數write_outputs()中關閉它們。看的正下方位置f.close()是相對於原來的代碼:

def write_outputs(divided_data, intervals, column_titles): 
    for x in range(len(divided_data)): 
     f = open(OUTPUT_DIR + str(intervals[x]) + "_min.csv", 'w') 
     f.write(','.join(map(str, column_titles))) 
     f.write('\n') 
     for y in range(len(divided_data[x])): 
     to_write = divided_data[x][y] 
     f.write(','.join(map(str,to_write))) 
     f.write("\n") 
     f.close() 
    return None 
+0

你是對的,我需要改變f.close()的縮進,但是這是一個複製/粘貼錯誤對不起。我會解決的。 – roganjosh

+0

我已修復了縮進,感謝您的注意。我還將您的反饋提供給main()聲明。因此,而不是aggregateData.main()(例如)我應該重命名該文件的「主」? – roganjosh

相關問題