golang 中 如何获取 变量的内存占用大小

2020-02-22 23:12:23 +08:00
 ruandao

如下

func getMemSize(v interface{}) int64 {
	// 看了下,unsafe.Sizeof 返回的是,变量的类型的内存占用,但是缺少 变量底层数据结构的内存占用?譬如 存储不同数量的 map,unsafe.Sizeof 返回的都是同样的大小
    // 有考虑使用 json.Marshal 但是, 看了下 json.Marshal 文档 的内容,好像也不对
}
7216 次点击
所在节点    问与答
3 条回复
zhujinliang
2020-02-23 00:21:51 +08:00
楼主实际需求表达的不是很明确,我按我的理解说一下:

你说的那种统计整个 map 占内存大小实际是很难实现,且不具备通用性。就像给你一堆文件,文件中又有相互引用,现在问你某文件和他所有引用的文件的大小之和类似。

另外,指针类型该如何统计,是算指针的大小还是算指向的结构体的大小?假设多个 key 指向同一个对象,是否需要去重?如果 a、b 同时有指针指向对象 c,那么统计 a 时是否要算上 c 的内存空间?

unsafe.Sizeof 给出的是结构体的大小,这个结果可以指示分配多少内存用于存放该结构体是安全的。对于 map 这样的数据结构,在初始化完毕后,还有根据存储数据多少动态申请及释放空间,语言层面是无法统计的。

如确有需要,建议使用变量自行统计,插入一个对象时对变量加上相应的值,移除时再减去
NeinChn
2020-02-23 03:25:37 +08:00
@zhujinliang 这个场景你说的都对
但是实际上 Java 是有成熟的 profiler 做这个事情的,你考虑的事情基本也在数据中有体现
一般数据大小分为 Shallow Size 和 Retained Size,应对的就是本身 object 大小 /加上所有引用的大小
如果 a,b 同时指向 C,算 retained size 分别是 a+c,b+c
还可以以 a,b 为 parent,大小总计就是 a+b+c。这个功能在查内存泄漏时偶尔会用到。
内存分析都是打 snapshot 的,所以没有什么动态的问题需要考虑,最多就是打多个 snapshot 做内存 diff ( MAT/JProfiler/JFlight )都有支持。
yatseni
2020-02-27 12:22:35 +08:00
看上去是要获取整个对象树的内存占用,这功能需要自己递归的计算吧

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/646701

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX