我的程序从操作系统获取内存但没有返回。它读取内存中的文件,处理它们,然后等待下一个文件。一般来说,我有小文件,但有时我有大文件。当我的程序处理大文件时,它会向操作系统请求大量内存,但不会将其返回。
我找到了与 using 相关的问题/答案debug.FreeOSMemory(),但它不适用于我的代码示例。
我在真实系统中遇到了问题,但我可以在一个小例子中重现它:
package main
import (
"fmt"
"math/rand"
"runtime"
"runtime/debug"
)
type Data struct {
a int
b int
c string
}
var letters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
func randSeq(n int) string {
b := make([]rune, n)
for i := range b {
b[i] = letters[rand.Intn(len(letters))]
}
return string(b)
}
func stat(description string) {
var rtm runtime.MemStats
runtime.ReadMemStats(&rtm)
fmt.Printf("%s -> Alloc: %d; Sys: %d\n", description, rtm.Alloc, rtm.Sys)
}
func mapAllocate() map[string]Data {
var data = make(map[string]Data)
for i := 0; i < 10000; i++ {
key := randSeq(100)
el := Data{
a: rand.Int(),
b: rand.Int(),
c: randSeq(rand.Intn(10000)),
}
data[key] = el
}
return data
}
func main() {
stat("Start program")
var result map[string]Data
for i := 0; i < 10; i++ {
result = mapAllocate()
stat("Map allocate")
result = make(map[string]Data)
runtime.GC()
debug.FreeOSMemory()
stat("GC call ")
}
fmt.Println(len(result))
runtime.GC()
debug.FreeOSMemory()
for true {
stat("Waiting ")
time.Sleep(30 * time.Second)
}
}
当然,我在实际应用中不会调用 GC。我在这里用它来演示我的问题。
如果理解正确:
程序从堆中分配内存。Go 运行时第一次没有足够的内存并从操作系统请求它。
我调用 GC,它从内存中释放对象。但是 Go 运行时不会将此内存返回给操作系统。
这对我来说是个问题,因为程序获取了大文件,获取了大量内存,并且在 OOM 杀手杀死程序的一个实例之前(几天)永远不会将其返回给操作系统。
为什么 Go 运行时不会将此内存返回给操作系统,我该如何解决?
慕容708150
呼如林
相关分类