简体   繁体   English

Java对象内存使用情况-IBM ivm 1.4.2

[英]Java Object memory usage - ibm jvm 1.4.2

Is it possible to find memory usage of object in java within application? 是否可以在应用程序内的Java中找到对象的内存使用情况?

I want to have object memory usage to be part of debug output when application runs. 我想让对象内存使用率成为应用程序运行时调试输出的一部分。 I don't want to connect using external application to VM. 我不想使用外部应用程序连接到VM。

I have a problem that few classes eats up huge amount of memory and causes memory problems, my app gets crash. 我有一个问题,很少有类会占用大量内存并导致内存问题,我的应用程序崩溃。 I need to find that memory usage (I am working with limited memory resources). 我需要找到内存使用情况(我正在使用有限的内存资源)。

EDIT: I am using java 1.4:/ 编辑:我正在使用Java 1.4:/

See my pet project, MemoryMeasurer . 参见我的宠物项目MemoryMeasurer A tiny example: 一个小例子:

long memory = MemoryMeasurer.measureBytes(new HashMap());

You may also derive more qualitative memory breakdown: 您还可以得出更多定性的内存故障信息:

Footprint footprint = ObjectGraphMeasurer.measure(new HashMap());

For example, I used the latter to derive the per entry cost of various data structures , where the overhead is measured in number of objects created, references, and primitives, instead of just bytes (which is also doable). 例如,我使用后者来推导各种数据结构每次输入成本 ,其中开销是根据创建的对象,引用和基元的数量而不是字节(也可以)来衡量的。 So, next time you use a (default) HashSet , you can be informed that each element in it costs 1 new object (not your element), 5 references, and an int, which is the exact same cost for an entry in HashMap (not unexpectedly, since any HashSet element ends up in a HashMap ), and so on. 因此,下次使用(默认) HashSet ,您会被告知,其中的每个元素花费1个新对象(不是您的元素),5个引用和一个int,这与HashMap的条目的花费完全相同(并不奇怪,因为任何HashSet元素都以HashMap结尾),依此类推。

You can use it on any object graph. 您可以在任何对象图上使用它。 If your object graph contains links other structures you do wish to ignore, you should use a predicate to avoid exploring them. 如果对象图包含您希望忽略的其他结构的链接,则应使用谓词来避免探索它们。

Edit Instrumentation is not available to Java 1.4 (wow, people still use that?!), so the memoryBytes call above wouldn't work for you. 编辑 Instrumentation对Java 1.4不可用(哇,人们还在用吗?!),因此上面的memoryBytes调用对您不起作用。 But the second would. 但是第二个会。 Then you can write something like this (if you are on a 32bit machine): 然后,您可以编写如下内容(如果您使用的是32位计算机):

long memory = footprint.getObjects() * 8 + footprint.getReferences() * 4 +
              footprint.getPrimitives().count(int.class) * 4 + 
              footprint.getPrimitives().count(long.class) * 8 + ...;

That gives you an approximation. 那给你一个近似值。 A better answer would be to ceil this to the closest multiple of 16: 更好的答案是将其设置为最接近的16的倍数:

long alignedMemory = (x + 15) & (~0xF); //the last part zeros the lowest 4 bits

But the answer might still be off, since if you find, say, 16 booleans, it's one thing if they are found in the same object, and quite another if they are spread in multiple objects (and cause excessive space usage due to aligning). 但是答案可能仍然是错误的,因为如果您发现例如16个布尔值,则在同一对象中找到它们是一回事,而如果它们分散在多个对象中则是另一回事(由于对齐导致过多的空间使用) 。 This logic could be implemented as another visitor (similar to how MemoryMeasurer and ObjectGraphMeasurer are implemented - quite simply as you may see), but I didn't bother, since that's what Instrumentation does, so it would only make sense of Java versions below 1.5. 可以将这个逻辑实现为另一个访问者 (类似于MemoryMeasurerObjectGraphMeasurer的实现方式-就像您可能看到的一样简单),但是我没有打扰,因为那是Instrumentation工作,所以它只对低于1.5的Java版本有意义。

Eclipse MAT是一个非常好的分析内存的工具。

jdk附带了一些工具,例如jmap和jhat,它们提供了对象级别的详细信息。

The folowing link provides a piece of Java Code computing the size of objects: 以下链接提供了一段Java代码,用于计算对象的大小:

http://www.javaworld.com/javaworld/javatips/jw-javatip130.html http://www.javaworld.com/javaworld/javatips/jw-javatip130.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM