Go语言使用size库计算内存时遭遇DATA RACE问题求助
Go size库计算map内存时的数据竞争问题
我在用Go的size库计算变量运行时内存消耗,核心调用逻辑是Of函数传入interface,内部调用sizeOf遍历字段计算大小:
func Of(v interface{}) int { // Cache with every visited pointer so we don't count two pointers // to the same memory twice. cache := make(map[uintptr]bool) return sizeOf(reflect.Indirect(reflect.ValueOf(v)), cache) }
当sizeOf处理map类型时,触发了数据竞争警告,对应的处理代码片段如下:
case reflect.Map: // return 0 if this node has been visited already (infinite recursion) if cache[v.Pointer()] { return 0 } cache[v.Pointer()] = true sum := 0 keys := v.MapKeys() for i := range keys { val := v.MapIndex(keys[i]) // calculate size of key and value separately sv := sizeOf(val, cache) if sv < 0 { return -1 } sum += sv sk := sizeOf(keys[i], cache) if sk < 0 { return -1 } sum += sk } // Include overhead due to unused map buckets. 10.79 comes // from https://golang.org/src/runtime/map.go. return sum + int(v.Type().Size()) + int(float64(len(keys))*10.79)
错误信息
读取操作:
WARNING: DATA RACE 00:03:27 Read at 0x00c000996330 by goroutine 98: 00:03:27 reflect.maplen() 00:03:27 /home/git/.gimme/versions/go1.21.1.linux.amd64/src/runtime/map.go:1411 +0x0 00:03:27 reflect.Value.MapKeys() 00:03:27 /home/git/.gimme/versions/go1.21.1.linux.amd64/src/reflect/value.go:1788 +0x1a4
写入操作:
Previous write at 0x00c000996330 by goroutine 99: 00:03:27 runtime.mapdelete_fast64() 00:03:27 /home/git/.gimme/versions/go1.21.1.linux.amd64/src/runtime/map_fast64.go:273 +0x0 00:03:27 net/http.(*Transport).setReqCanceler() 00:03:27 /home/git/.gimme/versions/go1.21.1.linux.amd64/src/net/http/transport.go:1156 +0x204 00:03:27 net/http.(*persistConn).roundTrip.func1() 00:03:27 /home/git/.gimme/versions/go1.21.1.linux.amd64/src/net/http/transport.go:2622 +0x9a 00:03:27 runtime.deferreturn() 00:03:27 /home/git/.gimme/versions/go1.21.1.linux.amd64/src/runtime/panic.go:477 +0x30 00:03:27 net/http.(*Transport).roundTrip()
我试过在keys := v.MapKeys()代码周围加互斥锁,但没效果。想知道问题根源和可行的解决方案。
内容的提问来源于stack exchange,提问作者Sid Sidhant
相关产品推荐
相关产品推荐

