我遇到了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
對不起,長職位,但我認爲糖化在一起位,我學過谷歌可能會讓我建立一個容易失敗的系統。
有**無**差的代碼這兩個比特之間。你甚至沒有製作第一個col_titles的副本,只是分配一個額外的名字。沒有可能的方式,一個變化可能導致內存泄漏;你的問題在別處。 –
@DanielRoseman這是讓我困惑的部分。我已經跑了20多次,結果總是一樣的;現在我想這可能是由於我用Enthought Canopy來運行代碼?奇怪的是 – roganjosh
。給col_titles添加一個額外的引用不應該對GC產生影響。直到腳本退出爲止,它將不會被GC'ed,因爲它綁定到全局'FIELDS'列表。請嘗試製作一個再現此問題的[mcve]。 –