Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does a native library use 1.5 times more memory when used by java as when used by a C-Programm under linux?

I've written a library in C which consumes a lot of memory (millions of small blocks). I've written a c program which uses this library. And I've written a java program which uses the same library. The Java program is a very thin layer around the library. Basically there is only one native method which is called, does all the work and returns hours later. There is no further communication between Java and the native library using the java invocation interface. Nor there are Java object which consume a noteworthy amount of memory.

So the c program and the Java program are very similar. The whole computation/memmory allocation happens inside the native library. Still. When executed the c program consumes 3GB of memory. But the Java program consumes 4.3GB! (VIRT amount reported by top)

I checked the memory map of the Java process (using pmap). Only 40MB are used by libraries. So additional libraries loaded by Java are not the cause.

Does anyone have an explanation for this behavior?

EDIT: Thanks for the answers so far. To make it a little bit more clearer: The java code does nothing but invoke the native library ONCE! The java heap is standard size (perhaps 60MB) and is not used (except for the one class containing the main method and the other class invoking the native library).

The native library method is a long running one and does a lot of mallocs and frees. Fragmentation is one explanation I thought of myself too. But since there is no Java code active the fragmentation behavior should be the same for the Java program and the c program. Since it is different I also presume the used malloc implementations are different when run in c program or in Java program.

like image 514
Eduard Wirch Avatar asked Jan 20 '10 16:01

Eduard Wirch


People also ask

Why Java consumes more memory?

Garbage collection. As you might recall, Java is a garbage-collected language. In order for the garbage collector to know which objects are eligible for collection, it needs to keep track of the object graphs. So this is one part of the memory lost to this internal bookkeeping.

Does Java use virtual memory?

That would seem to say that java applications do not use OS virtual memory. Or do only java objects load into heap, but actual data loads into virtual memory. Generally this is for Linux and Windows kernels.

Can a JVM use more memory than XMX?

Ever wondered why Java applications consume much more memory than the specified amount via the well-known -Xms and -Xmx tuning flags? For a variety of reasons and possible optimizations, the JVM may allocate extra native memory.


2 Answers

Just guessing: You might be using a non-default malloc implementation when running inside the JVM that's tune to the specfic needs of the JVM and produces more overhead than the general-purpose malloc in your normal libc implementation.

like image 138
Joachim Sauer Avatar answered Oct 13 '22 08:10

Joachim Sauer


Sorry guys. Wrong assumptions.

I got used to the 64MB the Sun Java implementations used to use for default maximum heap size. But I used openjdk 1.6 for testing. Openjdk uses a fraction of the physical memory if no maximum heap size was explicitly specified. In my case one fourth. I used a 4GB machine. One fourth is thus 1GB. There it is the difference between C and Java.

Sadly this behavior isn't documented anywhere. I found it looking at the source code of openjdk (arguments.cpp):

// If the maximum heap size has not been set with -Xmx,
// then set it as fraction of the size of physical memory,
// respecting the maximum and minimum sizes of the heap.
like image 44
Eduard Wirch Avatar answered Oct 13 '22 09:10

Eduard Wirch