golang map delete 会释放value吗

Python023

golang map delete 会释放value吗,第1张

不会释放value,仅仅标记为不可用,但实际内存还是在占用

package main

import (

"log"

"runtime"

)

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()

}

func initMap() {

intMap = make(map[int]int, cnt)

for i := 0 i < cnt i++ {

intMap[i] = i

}

}

func printMemStats() {

var m runtime.MemStats

runtime.ReadMemStats(&m)

log.Printf("Alloc = %v TotalAlloc = %v Sys = %v NumGC = %v\n", m.Alloc/1024, m.TotalAlloc/1024, m.Sys/1024, m.NumGC)

}

按删除键。在go语言中要删除,请发出按删除键即可删除。Go(又称Golang)是Google的RobertGriesemer,RobPike及KenThompson开发的一种静态强类型、编译型语言。

sync.Map是1.9才推荐的并发安全的map,除了互斥量以外,还运用了原子操作,所以在这之前,有必要了解下 Go语言——原子操作

go1.10\src\sync\map.go

entry分为三种情况:

从read中读取key,如果key存在就tryStore。

注意这里开始需要加锁,因为需要操作dirty。

条目在read中,首先取消标记,然后将条目保存到dirty里。(因为标记的数据不在dirty里)

最后原子保存value到条目里面,这里注意read和dirty都有条目。

总结一下Store:

这里可以看到dirty保存了数据的修改,除非可以直接原子更新read,继续保持read clean。

有了之前的经验,可以猜测下load流程:

与猜测的 区别

由于数据保存两份,所以删除考虑:

先看第二种情况。加锁直接删除dirty数据。思考下貌似没什么问题,本身就是脏数据。

第一种和第三种情况唯一的区别就是条目是否被标记。标记代表删除,所以直接返回。否则CAS操作置为nil。这里总感觉少点什么,因为条目其实还是存在的,虽然指针nil。

看了一圈貌似没找到标记的逻辑,因为删除只是将他变成nil。

之前以为这个逻辑就是简单的将为标记的条目拷贝给dirty,现在看来大有文章。

p == nil,说明条目已经被delete了,CAS将他置为标记删除。然后这个条目就不会保存在dirty里面。

这里其实就跟miss逻辑串起来了,因为miss达到阈值之后,dirty会全量变成read,也就是说标记删除在这一步最终删除。这个还是很巧妙的。

真正的删除逻辑:

很绕。。。。