tags:

views:

1313

answers:

5

How can I determine the address in memory of the Java heap for a JVM running in the current process? That is, get a void* pointer or equivalent to the contiguous area of memory that the JVM has allocated for the heap, using Java, C, or other calls?

Matlab has a JVM embedded in its process. The memory the JVM allocates is unavailable for Matlab arrays, and of this, the heap is important, because it takes a big contiguous chunk of memory and never shrinks, and Matlab also needs contiguous memory for its arrays. If the heap is reallocated during expansion, that could cause fragmentation.

I'd like to instrument my process to examine the interaction between the Java heap and Matlab's view of memory, and to find out when it moves due to resizing, preferably all from within the process. This needs the address of the heap. It's easy to find the heap size from java.lang.Runtime, but not its address in memory. How can this be done?

I'm running Sun's JRE 1.6.0_04 in a Matlab R2008b process on Windows XP and Server 2003. I realize this probably needs to be a vendor-specific technique. The process runs code we've written, so we can use custom Java, Matlab, JNI, and C/C++ code. Java method calls or supported hooks in the JVM would be preferred to low-level hackery.

EDIT: The goal of this is to examine the interaction between the JVM's GC and Matlab's GC. I have no need to see into the Java heap and won't be reading anything from that memory; I just want to see where it is in the context of the overall virtual memory space that Matlab's GC is also trying to fit data into.

+1  A: 

If you just want to get the JVM heap to shrink you could try playing with the gc parameters such as -XX:MaxHeapFreeRatio (see http://java.sun.com/javase/technologies/hotspot/vmoptions.jsp)

I don't think you can get a pointer to the Java heap with JNI. However, the Java heap is just memory allocated to the process by Windows from one of the process heaps.

You can get at the process heaps from your C++ code using the GetProcessHeaps function (http://msdn.microsoft.com/en-us/library/aa366571(VS.85).aspx) and then start walking through them with the HeapWalk function. There's a good example at http://www.abstraction.net/content/articles/analyzing%20the%20heaps%20of%20a%20win32%20process.htm. You might be able to spot which allocated blocks are used by the Java heap by looking for certain patterns of bytes (the JVM source code might give you some clues as to what to look for, but good luck figuring that out!)

This sounds promising; I hadn't known about GetProcessHeaps. Going to try throwing this together for our app.
Andrew Janke
"the Java heap is just memory allocated to the process by Windows from one of the process heaps.". This is not true, the Java heap is allocated (on Windows) via kernel32!VirtualAlloc and as such is not from one of the process heaps.
QAZ
+2  A: 

Stepping back a bit... Could you go with a fixed-size Java heap? At that point concerns about reallocation and fragmentation go away.

On a stand-alone Java invocation, that involve specifying something like -Xmx500m and -Xms500m for a 500Mb heap. You'd have to translate that into what matlab wants.

John M
This could help - but the tradeoff is the memory allocated to the Java heap can't be used for Matlab arrays. In some runs, users do Java heap-intensive GUI stuff, in others, M-code intensive numeric stuff. A fixed size heap would fix fragmentation at the cost of flexibility. That's actually why I want this instrumentation - to see whether the fixed heap tradeoff would be worthwhile by asking "how much fragmentation is happening due to heap realloc?"
Andrew Janke
A: 

The GC can move data at any time to compact the memory. So there is no fixed point for objects in the Java Heap. You can use a ByteBuffer.allocateDirect() which allocates memory in the "C" space rather than the heap and it is fixed in memory.

Peter Lawrey
I'm not looking for the location of individual objects within the Java heap, rather the location of the entire Java heap within the virtual address space of the process.
Andrew Janke
A: 

I don't think that there's a way do to what you want, without using a customized JVM. You could theoretically use OpenJDK and patch it or enable some tracing (not sure whether there's one that fits your needs). I think n external monitoring tool such as the process explorer could solve your problem

kohlerm
+1  A: 

A quick 'n dirty way to get the actual heap address of the JVM is to jump into WinDbg, attaching to the JVM and issue a single !address command. Somewhere around 0x2??????? (It differes between jvm versions but remains static for that version) will be a large VAD marked PAGE_EXECUTE_READWRITE, this is your JVM's heap in the process's memory.

To confirm, you can set a breakpoint on kernel32!VirtualAlloc and upon JVM initilization in the module JVM.DLL you will hit on the call to VirtualAlloc showing you the jvm allocation its heap. If you check out the code around this call you can see how the address is calculated.

QAZ
Sorry I took so long to accept; got peeled off on other work for a while. I hadn't known about WinDbg. Very useful.
Andrew Janke