本文最后更新于 2021年07月20日 已经是 681天前了 ,文章可能具有时效性,若有错误或已失效,请在下方留言。
首先我们看下面的代码
package main
import (
"fmt"
"runtime"
)
func main() {
v := struct{}{}
a := make(map[int]struct{})
printMemStats("After Map Make", a)
for i := 0; i < 10000; i++ {
a[i] = v
}
runtime.GC()
printMemStats("After Map Add 100000", a)
for i := 0; i < 10000-1; i++ {
delete(a, i)
}
runtime.GC()
printMemStats("After Map Delete 9999", a)
for i := 0; i < 10000-1; i++ {
a[i] = v
}
runtime.GC()
printMemStats("After Map Add 9999 again", a)
a = nil
runtime.GC()
printMemStats("After Map Set nil", a)
}
func printMemStats(mag string, mp map[int]struct{}) {
var m runtime.MemStats
runtime.ReadMemStats(&m)
fmt.Printf("[%v] map address = %p, memory = %vKB , GC Times = %v , Map Length = %d\n", mag, &mp, m.Alloc/1024, m.NumGC, len(mp))
}
执行结果
[After Map Make] map address = 0xc000006028, memory = 189KB , GC Times = 0 , Map Length = 0
[After Map Add 100000] map address = 0xc000006008, memory = 364KB , GC Times = 1 , Map Length = 10000
[After Map Delete 9999] map address = 0xc000006008, memory = 366KB , GC Times = 2 , Map Length = 1
[After Map Add 9999 again] map address = 0xc000006008, memory = 366KB , GC Times = 3 , Map Length = 10000
[After Map Set nil] map address = 0xc0000fa010, memory = 188KB , GC Times = 4 , Map Length = 0
分析
在golang中的,在我们删除map键值对的时候,并不会真正的删除,而是进行标记。那么随着键值对越来越多,甚至会引起OOM
解决方法
c := make(map[int]struct{})
for i := 0; i < 100; i++ {
c[i] = a[i]
}
a = c
这样就可以了