我目前正在Jetty中运行Grails应用程序。它工作正常,但占用的内存比我想要的多。
htop
表明Jetty的运行情况如下:java -server -Xmx256m -Xms256m -Xmn96m -XX:MaxPermSize=64m -Djetty.home=/home/...
在我看来,Jetty可能使用的最大内存应该是 about 256 + 64 = 320 MB
。相反,它看起来像这样:
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=...
显然我不希望内存使用量正好是320 MB,但它不应该接近吗?为什么它会是预期记忆的两倍?如果有的话,Java堆填满时不应该拒绝分配更多的空间吗?
我试图看到jmap
发生了什么事,但一切看起来都对我不错:
# 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.
据我所知,perm gen空间和堆空间都不满。那么什么呢〜用于400 MB的内存?我可以在Grails应用程序或Jetty中更改它以减少它吗?
我过去在Jetty上运行Grails应用程序,内存使用率很低。刚刚检查了一个,它使用的是220 MB内存,所以我不确定我做错了什么。
答案 0 :(得分:2)
JVM是consumes native resources的本机程序,包括本机内存。本机内存是运行时进程可用的内存,与Java应用程序使用的Java堆内存不同。每个虚拟化资源(包括Java堆和Java线程)都必须与运行时虚拟机使用的数据一起存储在本机内存中。 你也可以看看这个answer,它很好地解释了这个主题 这个thread显示了一些如何用Java泄漏本机内存的好例子 Jetty documentation也指这个主题 如果您使用的是JDK7,则可以使用VisualVM buffer monitor plugin来监视在垃圾收集堆之外分配的直接缓冲区。