Unused java heap memory is not getting released to OS even if i use the following VM options:
Still when more than 80 percent of heap memory is free, it is not getting released to OS
Java HotSpot(TM) 64-Bit Server VM (1.5.0_15-b04, mixed mode)
ParallelGC (otherwise known as throughput collector which is the default collector in server class VM)
i specified -Xms50M and -Xmx1000M as jvm arguments
OS: windows 7 professional (8 GB memory 64 bit OS)
tried using serialGC, with those heapfreeratio jvm args, still when more than 80 percent of heap memory is free, it is not getting released to OS
whether "AggressiveHeap" "UseAdaptiveSizePolicy" jvm options (which i didnt specify to jvm) has anything to do with this.
I don't think it's true that the JVM never releases memory back to the OS while it's running. Rather, it will do so on its own terms according to whatever algorithm is built in to that particular JVM implementation and whatever command line args we've given it to adjust that algorithms' parameters. It's just another one of the JVM's internal administrative tasks, like thread scheduling or physical memory layout of objects that's largely unspecified and in general unpredictable.
OK Jeff, I will qualify my response. In over a decade of my involvement with Java starting with jdk1.0.1 and going though to 1.7 using Sun implementations, Oracle implementations and IBM implementations I have never seen a JVM implementation that released memory back to the OS and have never seen a statement that said it did. You may be right in that it may be unspecified behaviour that the JVM implementers are free to handle as they wish but I have never seen an implementation that releases the memory.
FWIW, a quick google search for when does JVM return memory to OS gave this, which has a comment (presumably from somebody at Sun) saying, "The HotSpot JVM already will release memory back to the operating system if it is not needed for live Java objects."
Also, here it says, "To complicate matters further, the JVM may choose not to release unused memory back to the operating system," which suggests that it may also choose to release it back to the OS.
I have never seen a JVM implementation that released memory back to the OS
I (many years and versions ago) once played around with several Java versions and with some I was able to detect their returning memory to the OS, whereas with others not.
It depended on the Java version and not the platform (Windows or Linux).
There are differrences between how memory is managed when you use the client VM vs Server VM
From the FAQ on Java Hotspot VM
What's the difference between the -client and -server systems?
These two systems are different binaries. They are essentially two different compilers (JITs)interfacing to the same runtime system. The client system is optimal for applications which need fast startup times or small footprints, the server system is optimal for applications where the overall performance is most important. In general the client system is better suited for interactive applications such as GUIs. Some of the other differences include the compilation policy,heap defaults, and inlining policy.
I am guessing here, but I'm pretty sure that the Client VM will be more inclined to release memory back to the OS (and hence have a smaller footprint), whereas a server VM will be more inclined to keep the memory to itself (and hence improve performance) Allocation of memory at the OS level is not cheap, and if you have an application that is continuously running, it's better to keep the memory to yourself and reuse it. In OS that provide virtual memory, memory can get fragmented too just like your disk can get fragmented (although defragging the memory is much cheaper), and it's better to get one contiguous block of memory. The downside of keeping memory, is of course that the application would hog up system resources, and also startup time is also increased.
Server applications that are built in languages that do not provide GC, it's not uncommon to implement your own pooling of objects. C++ Std library had introduced an allocator module that allowed you to customize allocation mechanism. And the biggest reason for this was so you can implement your own custom pooling easily. Generally, you don't do pooling of objects in Java because the JVM is pooling the memory for you, so it's a moot point
IMO, at the end of the day, if you are building a server app, you shouldn;t be looking at the memory used by the JVM at the OS level. WHether or nor the JVM is releasing memory back to the OS is a red herring. What matters more is how much of your heap is allocated.