Go map 大小

本文介绍如何在Go语言中利用`MapSize`包计算map的内存占用,通过底层的runtime.hmap和unsafe包获取map分配的桶数量,尽管noverflow不完全准确,但结果与实际相差不大。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

如何得到一个 map 占用了多少内存

go get github.com/520MianXiangDuiXiang520/MapSize
package main

import (
	"fmt"
	"github.com/520MianXiangDuiXiang520/MapSize"
)

func main() {
	m := make(map[int]struct{})
	for i := 0; i < 100; i++ {
		m[i] = struct{}{}
	}
	fmt.Println(mapsize.Size(m)) // 1416
}

思路:

map 底层是 runtime.hmap 只需要使用 unsafe 将 map 指针对应的内存强转就可以得到 map 申请的桶的个数了,乘以键值的大小就可以算出内存占用情况:

func Size[K comparable, V any](m map[K]V) int64 {
	var zeroK K
	var zeroValue V
	keySize := unsafe.Sizeof(zeroK)
	valueSize := unsafe.Sizeof(zeroValue)
	vo := reflect.ValueOf(m)
	hm := (*hmap)(unsafe.Pointer(vo.Pointer()))
	bn := 1<<hm.B + uintptr(hm.noverflow)
	bz := unsafe.Sizeof(bmap{}) + (keySize+valueSize)*bucketCnt
	return int64(unsafe.Sizeof(hmap{}) + bz*bn)
}

注意:由于 noverflow 并不是真实的溢出桶数量,所以这种方法得到内存占用并不完全准确,但 map 本身的阔缩容用的也是 noverflow 所以与实际情况并不会差很多,通过 pprof 测试也几乎一致

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Junebao

如果你碰巧财力雄厚的话...

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值