Saturday, August 11, 2001 06:37 PM
The correspondence between the java.lang.Runtime memory figures and actual system memory usage is not close. Like most native applications, the Java interpreter never gives back memory it's taken from the system - so you shouldn't expect to see rising and falling numbers here matching what the Java GC is doing.
It is theoretically possible for an application to give back memory with the low-level sbrk() kernel call, but there are practical difficulties - the memory given back must be a contiguous chunk at the high end of the address space. That's virtually impossible without garbage collection (i.e., in most native applications) and also impossible with current implementations of libc's standard allocator (malloc()).
So why doesn't the Java interpreter, which does have GC, give back memory? My conjecture is that this would be vastly more trouble to implement (if even possible) than it's worth. Not to fear: garbage-collected memory is not lost, it's endlessly reused. It's just not returned to the system, where it would be reflected in falling memory usage values.
So, on to the questions:
1) The 37M includes the heap and stack sizes managed by the JVM, plus the overhead of managing those memory pools, plus allocations of non-objects made by native code - in other words, a lot of overhead. It might also (depending on top's behavior) include the shared memory occupied by the JVM's native code itself.
2) There's not much you can do about it. That overhead is the cost of running the Java interpreter above and beyond the heap and stack space for objects and the Java thread stacks.
3) The explanation at the start of this answer should address this question.