views:

630

answers:

4

What is the best way to tune a server application written in Java that uses a native C++ library?

The environment is a 32-bit Windows machine with 4GB of RAM. The JDK is Sun 1.5.0_12.

The Java process is given 1024MB of memory (-Xmx) at startup but I often see OutOfMemoryErrors due to lack of heap space. If the memory is increased to 1200MB, the OutOfMemoryErrors occur due to lack of swap space. How is the memory shared between the JVM and the native process?

Does the Windows /3GB switch have any effect with native processes and Sun JVM?

A: 

How is the memory shared between the JVM and the native process?

Sun's JVM's garbage collector is mark-and-sweep, with options to enable concurrent and incremental GC.

Well, more accurately, it's staged, and the above only applies to tenured (long-lived) objects. For young objects, GC is still done with a stop-and-copy collector, which is much better for working with short-lived objects (and all typical Java programs create many short-lived objects).

A copying collector walks over all elements in the heap, copying them to a new heap if they are referenced, and then discards the former heap. Thus 1M of live objects requires up to 2M of real memory: if every object is alive, there will be two copies of everything during garbage collection.

So the JVM requires far more system memory than is available to the code running within the VM, because there is a substantial overhead to management and garbage collection.

Does the Windows /3GB switch have any effect with native processes and Sun JVM?

The /3GB allows user virtual memory address space to be 3GB, but only for executables whose headers are marked with IMAGE_FILE_LARGE_ADDRESS_AWARE. As far as I am aware, Sun's java.exe is not. I don't have a Windows system here, so I can't verify.

ephemient
+1  A: 

I found some info on JNI memory management here, and here's the JVM JNI section on memory management.

Well having a 3GB user space over a 2GB user space should help, but if your having problems running out of swap space at 2GB, I think 3GB is just going to make it worse. How big is your pagefile? Is it maxed out?

You can get a better idea on you heap allocation by hooking up jconsole to your jvm.

Charlie
+2  A: 

I had lots of trouble with that setting (Java on 32-bit systems - msw and others) and they were all solved by reserving just *under 1GB of RAM to the JVM.

Otherwise, as stated, the actual occupied memory in the system for that process would be over 2GB; at that point I was having 'silent deaths' of the process - no errors, no warnings, just the process terminating very quietly.

I got more stability and performance running several JVM (each with under 1GB RAM) on the same system.

gvlx
A: 

You haven't explained your problem well enough, unfortunately. The real question is --- why is the Java process growing so much. Do you have a memory leak? Do you have a real reason to have that much data in the JVM?

Is the C++ library allocating its own memory from the C stack, or is it allocating memory from the Java object space, or is it doing something else entirely?

vy32