作爲我的的一部分轉到教程,我正在編寫跨多個文件的簡單程序計數單詞。我有幾個去例行程序用於處理文件和創建map[string]int
,告知發現了多少特定單詞。然後將地圖發送到縮小例程,該例程將值彙總到單個地圖。聽起來很直接,看起來像Go的完美(地圖減少)任務!轉:當重複使用地圖鍵時,內存佔用大量使用
我有大約10萬個文件,有160萬個獨特單詞。我發現我的內存使用量在運行代碼的過程中不斷快速增長,而且我的內存在大約一半的處理內存(12GB盒,7GB免費)內存不足。所以是的,它爲這個小數據集使用了千兆字節!
試圖找出問題出在哪裏,我發現減速器收集和彙總數據是責任。代碼如下:
func reduceWords (input chan map[string]int, output chan int) {
total := make(map[string]int)
for wordMap := range input {
for w, c := range wordMap {
total[w] += c
}
}
output <- len(total)
}
如果我從上面的示例中刪除了映射,內存保持在合理範圍內(幾百兆字節)。我發現了什麼,雖然,走的是一個字符串的副本也解決了這個問題,即下面的示例不吃掉我的記憶:
func reduceWords (input chan map[string]int, output chan int) {
total := make(map[string]int)
for wordMap := range input {
for w, c := range wordMap {
copyW := make([]byte, len(w)) // <-- will put a copy here!
copy(copyW, w)
total[string(copyW)] += c
}
}
output <- len(total)
}
是否有可能它的每一個迭代後不被破壞一個wordMap
實例時我直接使用該值? (作爲一名C++程序員,我對GC的直覺有限。)這是否是可取的行爲?難道我做錯了什麼?我應該對去還是對我自己感到失望?
謝謝!
直覺的榮譽,它本身就是問題!我忘了我必須從現在開始思考。我在開始時將每個文件轉換爲字符串,因爲我發現它更快,但沒有意識到這是錯誤的。感謝幫助! – tomasz
@tomasz程序的總內存消耗量應該不可能超過程序讀取的文件大小的總和。我假設每個不同的文件只讀一次。這些10k文件的總大小是多少?是超過1 GB? – 2012-04-30 05:13:10
@Atom,這是正確的,文件總共超過5GB。 – tomasz