Я думаю, что нашел проблему!Я нарезаю каждую строку большого файла.Возвращаемое значение []string
представляет собой фрагмент, содержащий подстроки исходной строки (строки файла).Теперь проблема в том, что каждая подстрока не является новой строкой.Is это просто slice
, в котором хранится ссылка на неразрезанную строку (строку файла!).Я сохраняю sliced[0]
для каждой строки, следовательно, я сохраняю ссылку на каждую строку файла.Сборщик мусора не будет касаться строки чтения, потому что у меня все еще есть ссылка на нее.Технически я читаю и сохраняю все строки файла в памяти.
Решение состоит в том, чтобы скопировать нужную мне часть (sliced[0]
) в новую строку, фактически теряя ссылку на всю строку.Я сделал это следующим образом:
sliced := strings.Split(scanner.Text(), ",")
key_rune_arr := []rune(sliced[0])
key := string(key_rune_arr) // now key is a copy of sliced[0] without reference to line
mp[key] = 2.2 //instead of mp[sliced[0]] = 2.2
Программа теперь становится:
package main
import (
"bufio"
"unsafe"
"fmt"
"log"
"os"
"runtime"
"strings"
)
func main() {
file, err := os.Open("file_address.txt")
if err != nil {
log.Fatal(err)
}
defer file.Close()
mp := make(map[string]float32)
var total_size int64 = 0
scanner := bufio.NewScanner(file)
var counter int64 = 0
for scanner.Scan() {
counter++
sliced := strings.Split(scanner.Text(), ",")
key_rune_arr := []rune(sliced[0])
key := string(key_rune_arr) // now key is a copy of sliced[0] without reference to line
mp[key] = 2.2 //instead of mp[sliced[0]] = 2.2
}
if err := scanner.Err(); err != nil {
log.Fatal(err)
}
fmt.Printf("loaded: %d. Took %d Mb of memory.", counter, total_size/1024.0/1024.0)
fmt.Println("Loading finished. Now waiting...")
var ms runtime.MemStats
runtime.ReadMemStats(&ms)
fmt.Printf("\n")
fmt.Printf("Alloc: %d MB, TotalAlloc: %d MB, Sys: %d MB\n",
ms.Alloc/1024/1024, ms.TotalAlloc/1024/1024, ms.Sys/1024/1024)
fmt.Printf("Mallocs: %d, Frees: %d\n",
ms.Mallocs, ms.Frees)
fmt.Printf("HeapAlloc: %d MB, HeapSys: %d MB, HeapIdle: %d MB\n",
ms.HeapAlloc/1024/1024, ms.HeapSys/1024/1024, ms.HeapIdle/1024/1024)
fmt.Printf("HeapObjects: %d\n", ms.HeapObjects)
fmt.Printf("\n")
}
Результат такой, какой я хотел:
loaded: 544594. Took 8 Mb id memory.Loading finished. Now waiting...
Alloc: 94 MB, TotalAlloc: 3986 MB, Sys: 135 MB
Mallocs: 1653590, Frees: 1108129
HeapAlloc: 94 MB, HeapSys: 127 MB, HeapIdle: 32 MB
HeapObjects: 545461
Done!