Reputation: 3146
I'm currently running a Grails application in Jetty. It's working fine, but taking more memory than I'd like.
htop
shows that Jetty is being run like so: java -server -Xmx256m -Xms256m -Xmn96m -XX:MaxPermSize=64m -Djetty.home=/home/...
It seems to me, then, that the maximum memory that Jetty could possibly use should be about 256 + 64 = 320 MB
. Instead, it looks like this:
PID USER PRI NI VIRT RES SHR S CPU% MEM% TIME+ Command 6256 jetty 20 0 2747M 623M 13732 S 0.0 31.3 1:28.06 /usr/lib/jvm/java-7-openjdk-amd64/jre/bin/java -server -Xmx256m -Xms256m -Xmn96m -XX:MaxPermSize=64m -Djetty.home=...
Obviously I wouldn't expect the memory usage to be exactly 320 MB, but shouldn't it be close? Why would it be double the expected memory? If anything, shouldn't Java refuse to allocate more space when the heap fills up?
I tried to see exaftly what's going on with jmap
, but everything looks right to me:
# jmap -heap 6256 Attaching to process ID 6256, please wait... Debugger attached successfully. Server compiler detected. JVM version is 23.7-b01 using thread-local object allocation. Parallel GC with 4 thread(s) Heap Configuration: MinHeapFreeRatio = 40 MaxHeapFreeRatio = 70 MaxHeapSize = 268435456 (256.0MB) NewSize = 100663296 (96.0MB) MaxNewSize = 100663296 (96.0MB) OldSize = 5439488 (5.1875MB) NewRatio = 2 SurvivorRatio = 8 PermSize = 21757952 (20.75MB) MaxPermSize = 67108864 (64.0MB) G1HeapRegionSize = 0 (0.0MB) Heap Usage: PS Young Generation Eden Space: capacity = 65208320 (62.1875MB) used = 33343488 (31.798828125MB) free = 31864832 (30.388671875MB) 51.13379396984924% used From Space: capacity = 17170432 (16.375MB) used = 0 (0.0MB) free = 17170432 (16.375MB) 0.0% used To Space: capacity = 18284544 (17.4375MB) used = 0 (0.0MB) free = 18284544 (17.4375MB) 0.0% used PS Old Generation capacity = 167772160 (160.0MB) used = 132604224 (126.46124267578125MB) free = 35167936 (33.53875732421875MB) 79.03827667236328% used PS Perm Generation capacity = 67108864 (64.0MB) used = 55899320 (53.30974578857422MB) free = 11209544 (10.690254211425781MB) 83.29647779464722% used 26872 interned Strings occupying 2932096 bytes.
As far as I can tell, neither the perm gen space nor the heap space are full. So what's all that ~400 MB of memory being used for? Is there something I can change in my Grails application or in Jetty to reduce it?
I've run Grails apps on Jetty in the past with low memory usage. Just checked one right now and it's sitting at 220 MB of memory used, so I'm not really sure what I'm doing wrong.
Upvotes: 1
Views: 710
Reputation: 20376
The JVM is a native program which consumes native resources, including native memory. Native memory is the memory available to the runtime process, as distinguished from the Java heap memory that a Java application uses. Every virtualized resource — including the Java heap and Java threads — must be stored in native memory, along with the data used by the virtual machine as it runs.
You can also take a look at this answer which explains this subject very nicely.
This thread show some nice examples of how to leak native memory with Java.
The Jetty documentation also refers to this subject.
If you are using JDK7 you can use the VisualVM buffer monitor plugin for monitoring direct buffers that are allocated outside of the garbage-collected heap.
Upvotes: 2