在go语言中,有两个内建函数分别是len(),cap(),前者用于获取容器的具体内容个数,后者用于获取容器分配的容量大小,但是这个cap对象是不能获取到map具体分配的容量大小的。有没有办法获取到呢,办法是有的,且看下文。

首先我们先使用gdb调试工具,查看一下map对象的具体结构是什么样子的。

一个及其简单的代码如下:

接下来我们编译这个简单的代码,并进行调试

# go build -o test -gcflags="-N -l" main.go 这里goflags是编译时指定的参数, -N 表示禁止优化,-l表示禁止内联。 便于调试

使用gdb进行调试

# gdb test
(gdb) b main.main
Breakpoint 1 at 0x401000: file /media/sf_goproject/src/map.go, line 3.
(gdb) r # 开始运行
Starting program: /media/sf_goproject/src/test
(gdb) n
m := make(map[string]int)
(gdb) ptype m

type = struct hash<string, int> {

int count;

uint8 flags;

uint8 B;

uint32 hash0;

struct bucket<string, int> *buckets;

struct bucket<string, int> *oldbuckets;

uintptr nevacuate;

[2]*[]*runtime.bmap *overflow;

} *

从上面的调试可以看到map对象的数据结构,在golang的runtime包的的haspmap.go中有这个结构的详细介绍:



所以B代表了map的容量 既然我们知道了数据的的结构,便可根据结构得到容量的内容。代码示例如下。


一些记录:

1. 在看许多文章中有说到map分配的键值被删除之后,内存是不会释放的。但是在我测试的过程中,发现内存是可以释放的。可能是版本的原因,测试的版本是1.7.1

2. map是非并发安全的,使用过程中需要自己去控制加锁。