V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
ruandao
V2EX  ›  问与答

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

  •  
  •   ruandao · 2020-02-22 23:12:23 +08:00 · 7169 次点击
    这是一个创建于 1737 天前的主题,其中的信息可能已经有所发展或是发生改变。

    如下

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

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

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

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

    如确有需要,建议使用变量自行统计,插入一个对象时对变量加上相应的值,移除时再减去
    NeinChn
        2
    NeinChn  
       2020-02-23 03:25:37 +08:00   ❤️ 1
    @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
        3
    yatseni  
       2020-02-27 12:22:35 +08:00
    看上去是要获取整个对象树的内存占用,这功能需要自己递归的计算吧
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3358 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 12:03 · PVG 20:03 · LAX 04:03 · JFK 07:03
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.