views:

49

answers:

2

Hello,

I'm using Eclipse 3.6 with latest Sun Java 6 on Linux (64 bit) with a larger number of large projects. In some special circumstances (SVN updates for example) Eclipse needs up to 1 GB heap. But most of the time it only needs 350 MB. When I enable the heap status panel then I see this most of the time:

350M of 878M

I start Eclipse with these settings: -Xms128m -Xmx1024m

So most of the time lots of MB are just wasted and are just used rarely when memory usage peaks for a short time. I don't like that at all and I want Eclipse to release the memory back to the system, so I can use it for other programs.

When Eclipse needs more memory while there is not enough free RAM than Linux can swap out other running programs, I can live with that. I heard there is a -XX:MaxHeapFreeRatio option. But I never figured out what values I have to use so it works. No value I tried ever made a difference.

So how can I tell Eclipse (Or Java) to release unused heap?

A: 

You can go to the Preferences -> General and check the Show heap status. This activate a nice view of your heap in the corner of Eclipse. Something like this:

alt text

If you click the trash bin, it will try to run garbage collection and return the memory.

nanda
I know this status display (Even mentioned it in my question) and I know this trash button but it only runs the garbage collector and does NOT return any memory to the system. So if Eclipse had a short memory usage peak of 1 GB then the heap size stays at 1 GB forever (until I restart Eclipse), even when only 300 MB of the heap is actually used.
kayahr
A: 

Java's heap is nothing more than a big data structure managed within the JVM process' heap space. The two heaps are logically-separate entities even though they occupy the same memory.

The JVM is at the mercy of the host system's implementations of malloc(), which allocates memory from the system using brk(). On Linux systems (Solaris, too), memory allocated for the process heap is almost never returned, largely because it becomes fragmented and the heap must be contiguous. This means that memory allocated to the process will increase monotonically, and the only way to keep the size down is not to allocate it in the first place.

-Xms and -Xmx tell the JVM how to size the Java heap ahead of time, which causes it to allocate process memory. Java can garbage collect until the sun burns out, but that cleanup is internal to the JVM and the process memory backing it doesn't get returned.


Elaboration from comment below:

The standard way for a program written in C (notably the JVM running Eclipse for you) to allocate memory is to call malloc(3), which uses the OS-provided mechanism for allocating memory to the process and then managing individual allocations within those allocations. The details of how malloc() and free() work are implementation-specific.

On most flavors of Unix, a process gets exactly one data segment, which is a contiguous region of memory that has pointers to the start and end. The process can adjust the size of this segment by calling brk(2) and increasing the end pointer to allocate more memory or decreasing it to return it to the system. Only the end can be adjusted. This means that if your implementation of malloc() enlarges the data segment, the corresponding implementation of free() can't shrink it unless it determines that there's space at the end that's not being used. In practice, a humongous chunk of memory you allocated with malloc() rarely winds up at the very end of the data segment when you free() it, which is why processes tend to grow monotonically.

Blrfl
Does that mean that this is a operating system issue and memory is returned to the system correctly on Windows? Are there any official sources for the statement that it doesn't work on Linux?
kayahr
It isn't an OS problem. In your case it's a combination of how much process memory your JVM allocates for Java's heap, how it's freed and how process memory is handled by the allocator used by the JVM (usually libc's `malloc()`). I've elaborated a bit more on it in my original answer. Any "official statement" on how a particular implementation behaves would be the source for that implementation.
Blrfl