【问题标题】:Java Memory OverheadJava 内存开销
【发布时间】:2011-02-12 20:33:44
【问题描述】:

我想问一下java中的内存开销, 我有一个大的 ArrayList(61,770 个项目),并试图计算每个项目占用的内存量(计算对象及其 ArrayList 条目), 通过分析应用程序,我了解到在加载所有数据后,堆占用约 25Mb。 当 ArrayList 只有 2 个项目时,堆占用 ~1Mb ,大致如下:

(24*1024*1024)/61,768 = 407 字节。

然而,当我计算每个对象的字段时,我得到 148 个字节(不包括 ArrayList,假设 int=4,float=4,reference=4),我很好奇要知道所有这些额外的字节是从哪里来的......

我可以猜测,由于我存储在 ArrayList 中的对象正在实现一个接口,它们存储了额外的值,也许 VM 为每个实现的方法存储了一个 4 字节的函数指针? 他们实现的接口有 20 个函数,因此增加了 80 个字节,总共 228 个字节,仍然没有接近测量的 400 个字节。

任何帮助将不胜感激。


哇,感谢所有精彩的答案。

@Bolo:感谢您的链接,对于这个类,我测量每个对象约 350 个字节,所以我至少可以确认大量内存使用的来源。

@Yuval A:感谢您的介绍,这是一个宝贵的信息来源。

@Ukko:注意点。

@Jayan:现在 NetBeans 分析器在我尝试转储堆时给我错误,稍后再试。

【问题讨论】:

  • 这篇文章可能对你有用:javaworld.com/javaworld/javatips/jw-javatip130.html
  • 如果你从 new ArrayList(61770) 开始而不是 new ArrayList() 然后让它自动调整大小,你也会得到不同的开销。在检查内存使用之前,您是否设置了正确的大小?
  • @flamealpha: 61 770 并不大 :) 我的 HashMap 太大了,以至于大多数系统都崩溃了……这就是为什么我用 Trove 的 TIntIntHashMap 这只是 所以 更多的内存/速度效率 :) 唉,它只适用于原语 :-/

标签: java memory interface arraylist overhead


【解决方案1】:

arraylist 消耗的内存有点模糊。

在适当的阶段对进程进行堆转储 - 在完全分配值之后。然后使用内存分析器(来自 eclipse)之类的工具。

您会发现浅层和保留堆大小。

【讨论】:

    【解决方案2】:

    ArrayList 通常大于元素的数量。使用getCapacity() 获取底层数组的当前大小。

    【讨论】:

      【解决方案3】:

      这些结果并不令人惊讶。 JVM 为每个对象增加了大量的开销。

      由于 JVM 内存开销,单个对象的预期大小大约是预期大小的两倍并不少见。

      This presentation 对 Java 中各种数据结构内存使用情况进行了精彩、深入的解释和概述。

      【讨论】:

        【解决方案4】:

        您的方法的一个大问题是与垃圾收集器的交互。它基本上使您提出的任何测试从外部完全不透明。

        如果你想这样做,作为一个思想实验,你应该这样做

        1. 启动 JVM 并执行几次全局 GC 以清除所有垃圾
        2. 测量堆大小和 Java 关于它有多少可用空间的概念。
        3. 运行测试
        4. GC 几次
        5. 从第 2 步重做测量

        在所有这些和一点数学之后,你会更接近,但仍然不对。唯一真正的解决方案是像其他人提到的那样实际询问实现。或者从实现的知识中弄清楚。

        【讨论】:

          【解决方案5】:

          附带说明一下,既然您确切知道 ArrayList 中有多少对象,为什么不直接使用数组[]?里面的物体数量会变吗?

          【讨论】:

          • 这只是一个例子,要加载的元素的确切数量不是预先确定的,我更关心的是数组指向的对象的内存开销。
          猜你喜欢
          • 1970-01-01
          • 2011-11-16
          • 2020-12-13
          • 2010-12-04
          • 1970-01-01
          • 2017-08-30
          • 2019-12-06
          • 1970-01-01
          • 2017-02-20
          相关资源
          最近更新 更多