对于频繁增删map的场景,我们很关心map的内存是否会自动释放。
先说结论:
-
如果删除的元素是值类型,如int,float,bool,string以及数组和struct,map的内存不会自动释放
-
如果删除的元素是引用类型,如指针,slice,map,chan等,map的内存会自动释放,但释放的内存是子元素应用类型的内存占用
-
将map设置为nil后,内存被回收
实验
以子元素是整形和map为例
重要一点:
申请一个全局map来保证内存被分配到堆上面
原因请参照:golang的gc回收针对堆还是栈?变量内存分配在堆还是栈?
实验1
普通的map,map保存到是int到int的映射,会执行delete删除map的每一项,执行垃圾回收,看内存是否被回收,map设置为nil,再看是否被回收。
package main
import (
"log"
"runtime"
)
var lastTotalFreed uint64
var intMap map[int]int
var cnt = 8192
func main() {
printMemStats()
initMap()
runtime.GC()
printMemStats()
log.Println(len(intMap))
for i := 0; i < cnt; i++ {
delete(intMap, i)
}
log.Println(len(intMap))
runtime.GC()
printMemStats()
intMap = nil
runtime.GC()
printMemStats