题
我想询问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在尝试倾倒堆时给我错误,稍后再尝试。
解决方案
其他提示
阵列列表大多要大于元素数量。采用 getCapacity()
要获取基础阵列的当前大小。
您的方法一个大问题是与垃圾收集器的互动。基本上,它像您提出的那样从外部完全不透明。
作为一个思想实验,如果您想这样做
- 启动您的JVM,并进行几个全球GC,以将所有垃圾淘汰
- 测量堆尺寸和Java的概念,即它拥有多少可用空间。
- 进行测试
- GC几次
- 从步骤#2重做测量
毕竟,您将更加接近,但仍然不对。唯一真正的解决方案是像其他人一样实际询问实施。或从对实施的知识中弄清楚。
Arraylist消耗的记忆有点模糊。
在适当的阶段进行该过程的堆转储 - 在值完全分配之后。然后使用内存分析仪(来自Eclipse)之类的工具。
您可以填充发现浅层和保留堆尺寸。
附带说明,由于您确切地知道您的数组列表中会有多少个对象,所以为什么不使用阵列[]?那里的对象数量会更改吗?