Java 内存开销
我想问一下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 探查器给我错误,稍后再试。
I would like to ask about Memory Overhead in java,
I have a large ArrayList (61,770 items), and trying to calculate the amount of memory taken by each item (counting the object and its ArrayList entry),
by profiling the app i get that after all the data is loaded, the heap takes ~ 25Mb.
when the ArrayList has only 2 items the heap takes ~1Mb , so roughly:
(24*1024*1024)/61,768 = 407 bytes.
however, when i count the fields of the each object, i get 148 bytes(not including the ArrayList, and assuming int=4,float=4,reference=4), I am curious to know where did all of those extra bytes came from...
i can guess that since the objects I store in the ArrayList are implementing an interface, they store extra values, maybe the VM stores a 4byte function pointer for each implemented method?
the interface they implement have 20 functions so thats 80 more bytes, totaling 228 bytes, still not close to the 400 bytes measured.
any help would be appreciated.
wow, thanks for all the great answers.
@Bolo: thanks for the link ,with this class i measure ~350 bytes per object so I can least confirm the source of the large memory usage.
@Yuval A: thank you for that presentation, a valuable source of information.
@Ukko: point noted.
@Jayan: right now NetBeans profiler is giving me errors when i try to dump the heap, will try later again.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
这些结果并不令人意外。 JVM 给每个对象增加了大量的开销。
由于 JVM 内存开销,单个对象的预期大小大约是预期大小的两倍并不罕见。
此演示文稿非常精彩, - Java中各种数据结构内存使用的深度、解释和概述。
These results are not surprising. The JVM adds enormous amounts of overhead to each object.
About double the expected size for a single object, due to JVM memory overhead, is not uncommon.
This presentation has a wonderful, in-depth, explanation and overview of various data structure memory usage in Java.
ArrayList 通常大于元素的数量。使用 getCapacity() 获取底层数组的当前大小。
An ArrayList ist mostly bigger than the number of elements. Use
getCapacity()
to get the current size of the underlying array.您的方法的一个大问题是与垃圾收集器的交互。它基本上使任何像您所提议的测试从外部完全不透明。
作为一个思想实验,如果您想这样做,您应该
经过所有这些操作和一些数学计算,您会更接近,但仍然不正确。唯一真正的解决方案是像其他人提到的那样实际询问实施情况。或者从实现的知识中找出答案。
A big problem with your approach is the interaction with the garbage collector. It basically makes any test like you have proposed totally opaque from the outside.
As a thought experiment if you wanted to do this you should
After all that and a bit of math you will be closer but still not right. The only real solution is to actually ask the implementation like other people have mentioned. Or figure it out from knowledge of the implementation.
arraylist 消耗的内存有点模糊。
在适当的阶段对进程进行堆转储 - 在值完全分配之后。然后使用内存分析器(来自 eclipse)等工具。
您将找到浅堆和保留堆大小。
Memory consumed by arraylist is a little vague.
Take a heap dump of the process at appropriate stage - after values are fully assigned. Then use tools like memory analyser (from eclipse).
You fill find shallow and retained heap sizes.
附带说明一下,既然您确切知道 ArrayList 中将包含多少个对象,为什么不直接使用 array[] 呢?里面的物体数量会改变吗?
As a side note, since you know exactly how many objects will be in your ArrayList, why not just use an array[]? Will the number of objects in there change?