9

I have a java application which when in idle state before any complex executions, uses 23 MB in Heap and the java.exe process size in TaskManager was around 194 MB. After some complex operations, the size of java.exe grew up to around 500MB and the heap size also grew up. The Heap size is reduced back to 23MB after a few full GC by calling System.gc() method. But the size of java.exe reduced to around 237MB from around 600MB which still have around 43 MB of data in it. Is there a way to reduce this? Or is that due to some behavior?

4

2 回答 2

14

This is normal, don't worry. JVM acquires memory when it needs to execute some complex logic. When java is done processing the tasks the JVM will still keep that memory as a reserved space and is not released back to the OS. This architecture helps in performance because JMV does not have to request the same memory again from the underlying OS. It will still be within the range you define in -Xmx JVM parameter.

See this IBM link for some interesting details. http://www-01.ibm.com/support/docview.wss?uid=swg21326774

Unfortunately this is one of the grey areas of JVM; you really don't have much of a control on how OS and JVM share memory between each other. Think of JVM as a Virtual OS that requires some memory to run. Both your parent OS and the VM are hungry for resources and want to hang on to the acquired resources the as much memory as possible. Requesting for more memory from OS is a time consuming operation so most of the JVMs do not release the memory back to the OS even when they don't need it anymore.

See this white paper from Oracle for more details on internal JVM memory management. http://www.oracle.com/technetwork/java/javase/memorymanagement-whitepaper-150215.pdf

I would suggest you to read the IBM link first and then you can delve into the weird world of memory explained in the white paper. Both of these links are very informative and interesting.

于 2013-05-20T13:17:08.397 回答
2

java进程的操作系统足迹由

  • java堆(它的大小受限制-Xmx
  • java 类相关元数据(或 HotSpot JVM 中的永久生成)
  • 通过 NIO 访问的非堆内存
  • java线程的堆栈空间

一些垃圾收集算法会将空闲内存返回给操作系统,而其他则不会。在 HotSpot JVM 中,串行旧空间收集器(通常默认启用)正在将内存返回给操作系统(因此您可以看到进程的缩小)。但是,其他收集器(例如-XX:+UseParallelOldGCor )-XX:+UseConcMarkSweepGC永远不会将未使用的堆内存返回给操作系统。

HotSpot JVM 具有管理/限制上述所有内存区域的选项,您可以在我的博客中找到与内存大小和 GC 调整相关的 JVM 选项的完整列表。

于 2013-05-20T15:09:54.680 回答