我想询问java中的内存开销,我有一个大的arraylist(61,770个项目),并试图通过分析应用程序来计算每个项目(计算对象及其arraylist条目)所取的内存量加载所有数据后,堆的时间约为25mb。当阵列列表只有2个项目时,堆大约1MB,因此大致:

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

然而, ,当我计算每个对象的字段时,我会得到148个字节(不包括阵列列表,并假设int = 4,float = 4,参考= 4),我很想知道所有这些额外字节来自哪里...

我可以猜测,由于我存储在ArrayList中的对象正在实现接口,因此它们存储了额外的值,也许VM存储了每个实现方法的4byte函数指针?他们实现的界面具有20个功能,因此多80个字节,总计228个字节,仍然不接近所测量的400个字节。

任何帮助,将不胜感激。


哇,谢谢您的所有好答案。

@Bolo:感谢您的链接,使用此类i测量每个对象〜350字节,因此我至少可以确认大型内存使用的来源。

@Yuval A:谢谢您的演讲,这是宝贵的信息来源。

@ukko:点指的是。

@Jayan:现在,Netbeans Profiler在尝试倾倒堆时给我错误,稍后再尝试。

有帮助吗?

解决方案

这些结果不足为奇。 JVM向每个对象添加了大量的开销。

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

这个演示文稿 对Java中各种数据结构内存的使用情况有一个奇妙的,深入的解释和概述。

其他提示

阵列列表大多要大于元素数量。采用 getCapacity() 要获取基础阵列的当前大小。

您的方法一个大问题是与垃圾收集器的互动。基本上,它像您提出的那样从外部完全不透明。

作为一个思想实验,如果您想这样做

  1. 启动您的JVM,并进行几个全球GC,以将所有垃圾淘汰
  2. 测量堆尺寸和Java的概念,即它拥有多少可用空间。
  3. 进行测试
  4. GC几次
  5. 从步骤#2重做测量

毕竟,您将更加接近,但仍然不对。唯一真正的解决方案是像其他人一样实际询问实施。或从对实施的知识中弄清楚。

Arraylist消耗的记忆有点模糊。

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

您可以填充发现浅层和保留堆尺寸。

附带说明,由于您确切地知道您的数组列表中会有多少个对象,所以为什么不使用阵列[]?那里的对象数量会更改吗?

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top