是否可以在应用程序中查找 java 中对象的内存使用情况?
我希望在应用程序运行时将对象内存使用情况作为调试输出的一部分。 我不想使用外部应用程序连接到 VM。
我有一个问题,很少有类会占用大量内存并导致内存不足 问题,我的应用程序崩溃了。我需要找到内存使用情况(我的内存资源有限)。
编辑:我正在使用 java 1.4:/
最佳答案
查看我的宠物项目,MemoryMeasurer .一个小例子:
long memory = MemoryMeasurer.measureBytes(new HashMap());
您还可以得出更多定性的内存分解:
Footprint footprint = ObjectGraphMeasurer.measure(new HashMap());
比如我用后者推导了per entry cost of various data structures ,其中开销以创建的对象、引用和原语的数量来衡量,而不仅仅是字节(这也是可行的)。因此,下次您使用(默认)HashSet
时,您会被告知其中的每个元素都需要 1 个新对象(不是您的元素)、5 个引用和一个 int,它们完全相同HashMap
中条目的成本(这并不意外,因为任何 HashSet
元素最终都在 HashMap
中),等等。
您可以在任何对象图上使用它。如果您的对象图包含您确实希望忽略的其他结构的链接,您应该使用谓词来避免探索它们。
编辑 Instrumentation
不适用于 Java 1.4(哇,人们还在使用它?!),所以上面的 memoryBytes
调用不会不适合你。但是第二个会。然后你可以这样写(如果你在 32 位机器上):
long memory = footprint.getObjects() * 8 + footprint.getReferences() * 4 +
footprint.getPrimitives().count(int.class) * 4 +
footprint.getPrimitives().count(long.class) * 8 + ...;
这给了你一个近似值。更好的答案是将其限制为最接近的 16 的倍数:
long alignedMemory = (x + 15) & (~0xF); //the last part zeros the lowest 4 bits
但答案可能仍然是错误的,因为如果你发现,比方说,16 个 boolean 值,如果它们在同一个对象中找到是一回事,如果它们分布在多个对象中则完全是另一回事(并导致过多的空间使用,因为对齐)。此逻辑可以实现为另一个 visitor (类似于 MemoryMeasurer 和 ObjectGraphMeasurer 的实现方式 - 正如您所见,非常简单),但我没有打扰,因为那是 Instrumentation
所做的,所以它只对 Java 有意义低于 1.5 的版本。
关于Java 对象内存使用 - ibm jvm 1.4.2,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3966411/