2

I was fiddling with Java heap for sometime. Using JVMTI , we can keep track of java heap.

But is there any way to achieve the same using pure java ?

I am using java instrumentation and asm framework for class transformation in runtime.

My objective is to keep track of every single object created , which means I need to check their sizes periodically. I can check if new object is created using asm. What I need is to check the sizes of the object created from the heap space.

Any pointers in this regard ?

edited on 28th December 2013

Ok , I was able to do something from ASM though it might not be the best possible solution ( best way is JVMTI that I completely agree ).

I had to override visitVarInsn (for local variables) , visitFieldInsn ( for instance and class variable) and visitTypeInsn (for NEW and NEWARRAY objects getting created )

Every time a new object gets created , I record the object ( yeah , this is not a good way I know , and this may cause resource leak. If you have any better solution , please tell me . I need it so badly [:( ] ) And I periodically check the object size.

Can you please provide me with better options ? (As Stephen has rightly pointed out , this object recording is definitely not going to work , but I am not comfortable with JVMTIeither [:(]). Also , pardon my ignorance , I could not find suitable MXBean methods.

MemoryMXBean has getHeapMemoryUsage() , but I can not track individual object size from this method. May be I should write my own MBean .

2
  • 1
    Have you looked at visualvm? Commented Dec 27, 2013 at 6:16
  • @ElliottFrisch : yes , but I believe it uses JVMTI . Commented Dec 27, 2013 at 6:31

3 Answers 3

3

I guess you could do it in theory. The (shallow) size of an object is easy to calculate from the number and type of the object's fields, and you could use the ASM instrumentation to insert code into to each constructor to record the size (somewhere) each time an object is constructed.

Dealing with arrays would be tricky. Array allocation doesn't entail a constructor, so you would need to instrument all of the places where arrays are created. Since some of those places could be in native code, it is hard to see how you would do this.

Another tricky case would be dealing with things that create objects without calling their constructors; e.g. Object Serialization and native cloning.

So all in all, this is probably NOT a practical approach.


The other point is that anything that uses ASM and similar stuff is arguably not "Pure Java" ... unless the usage is actually part of the JVM itself.

Sign up to request clarification or add additional context in comments.

6 Comments

I am using visitTypeInsn for tracking object instantiation. But , after the object is created , how can I deal with it ? I need to have the object list stored in some collection object , right ?
You should just record the objects' sizes in your stats. If you start recording the objects themselves, you are liable to create a massive storage leak. But like I said, I don't think this approach is practical. You will get more accurate results with fewer problems using JVMTI. (What is your problem with using it??)
It should also be pointed out that this kind of memory-use calculation inside the JVM is for entertainment -- I mean estimate -- purposes only. If you want to see useful memory use statistics, use JMX. When you throw in things like compressed OOPs and escape analysis, you really can't reliably determine how much heap an object is going to take up.
@CharlesForsythe : Actually , one of my key requirement is to be backward compatible to JDK 1.5 . And I had checked with various MXBeans. MemoryMXBean , MemoryPoolMXBean , MemoryManagerMXBean give useful information regarding heap , but I can not track any particular object size from them. May be I am missing out something while using JMX. Am I right ?
@StephenC : Yes , I do completely agree with you. Using JVMTI would have given me complete picture in a few hiccups. But , to be honest , I don't feel comfortable in JVMTI . If nothing can be done in java perspective , then I would have no choice but to move to JVMTI.
|
1

Since you are using Instrumentation, you already have access to an API that tells you the object sizes. The very same Instrumentation class that you use to modify the byte code of the classes provides the method getObjectSize(Object).

The resource leak you mention regarding your object tracking can be solved easily. Just put the objects into WeakReferences. Then you can use a ReferenceQueue to learn when the object has been garbage collected which is an important feature when you want to track the heap usage.

But I’m not quite sure what you want to achieve exactly.

By the way, as far as I know, JVisualVM does not use JVMTI. But JVisualVM does not track every object, either. A full heap analysis requires a heap dump. This can be done using the MXBean with the name "com.sun.management:type=HotSpotDiagnostic" sending the method invocation dumpHeap(String outputFile, boolean live).

4 Comments

Yes I am using the getObjectSize(Object) method and then I am using reflection for traversing through the object to get its actual size. Okk.. I am gonna try the ReferenceQueue thing and update you accordingly.
I just want to track the object sizes , that's it. :-) Yes , I could do it using taking heap dump , but I guess taking too many (and frequent ) heap dump might be expensive for the application
Please correct me if I am wrong. If I put the objects in WeakHashMap , and put them as keys , then jvm itself will check for weak references and remove the entries from map whenever an object is garbage collected.
That’s correct. But you have to take care that the value must not reference the keys, neither directly nor indirectly, as otherwise the keys will never get collected. WeakHashMap uses WeakReferences for the keys and a ReferenceQueue internally so if you want a HashMap semantic, it is the way to go. But there’s a catch: it does not have IdentityHashMap semantic.
0

Use the Runtime class

    long MEGABYTE = 1024L * 1024L;
    Runtime runtime = Runtime.getRuntime();
    runtime.gc();
    System.out.println("Total Memory : " + runtime.totalMemory()/MEGABYTE);
    System.out.println("Used Memory  : " + (runtime.totalMemory() - runtime.freeMemory()) / MEGABYTE);
    System.out.println("Free Memory  : " + runtime.freeMemory() / MEGABYTE);

1 Comment

Hi @Ankit , this will give the approximate value based on JVM size. But I want each of the object size from the heap. Not only that , I want to check the number of objects in the heap

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.