是否有可能在应用程序中找到java中对象的内存使用情况?
我希望在应用程序运行时将对象内存使用作为调试输出的一部分。 我不想使用外部应用程序连接到VM。
我遇到的问题是很少有类占用大量内存并导致内存 问题,我的应用程序崩溃。我需要找到内存使用情况(我正在使用有限的内存资源)。
编辑:我使用的是java 1.4:/
答案 0 :(得分:6)
参见我的宠物项目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个布尔值,那么如果它们存在于同一个对象中则是一回事,如果它们分布在多个对象中则是另一回事(并导致过多的空间使用)对齐)。这个逻辑可以实现为另一个visitor(类似于MemoryMeasurer和ObjectGraphMeasurer的实现 - 很简单,就像你看到的那样),但我没有打扰,因为那是{{ 1}}确实如此,因此它只能理解1.5以下的Java版本。
答案 1 :(得分:1)
Eclipse MAT是分析内存的一个非常好的工具。
答案 2 :(得分:0)
jdk附带了一些工具,例如jmap和jhat,它们提供了对象级别的细节。
答案 3 :(得分:0)
以下链接提供了一段计算对象大小的Java代码:
http://www.javaworld.com/javaworld/javatips/jw-javatip130.html