我正在使用Eclipse 3.6和Linux(64位)上的最新Sun Java 6以及大量项目。在某些特殊情况下(例如SVN更新),Eclipse需要最多1 GB的堆。但大多数时候它只需要350 MB。当我启用堆状态面板时,我大部分时间都会看到这个:
350M的878M
我使用以下设置启动Eclipse:-Xms128m -Xmx1024m
因此,大多数时候MB的浪费很少,而且只是在内存使用率达到峰值时很少使用。我根本不喜欢它,我希望Eclipse将内存释放回系统,所以我可以将它用于其他程序。
当Eclipse需要更多内存而没有足够的可用RAM而Linux可以换掉其他正在运行的程序时,我可以忍受。我听说有一个-XX:MaxHeapFreeRatio选项。但我从来没有弄清楚我必须使用什么价值,所以它有效。我试过的任何价值都没有带来任何影响。
那么如何告诉Eclipse(或Java)发布未使用的堆?
答案 0 :(得分:11)
找到解决方案。我将Java切换为使用G1垃圾收集器,现在HeapFreeRatio参数按预期工作。所以我在eclipse.ini中使用这些选项:
-XX:+UnlockExperimentalVMOptions
-XX:+UseG1GC
-XX:MinHeapFreeRatio=5
-XX:MaxHeapFreeRatio=25
现在当Eclipse为一项复杂的操作耗尽超过1 GB的RAM并在垃圾收集后切换回300 MB时,内存实际上会被释放回操作系统。
答案 1 :(得分:2)
您可以转到Preferences -> General
并查看Show heap status
。这会在Eclipse的角落激活堆的漂亮视图。像这样:
如果单击垃圾桶,它将尝试运行垃圾收集并返回内存。
答案 2 :(得分:1)
Java的堆只不过是JVM进程堆空间中管理的大数据结构。这两个堆是逻辑上分离的实体,即使它们占用相同的内存。
JVM受主机系统malloc()
实现的支配,它使用brk()
从系统分配内存。在Linux系统(Solaris也是如此)上,几乎从不返回为进程堆分配的内存,主要是因为它变得碎片化并且堆必须是连续的。这意味着分配给进程的内存将单调增加,并且保持大小减小的唯一方法是不首先分配它。
-Xms
和-Xmx
告诉JVM如何提前调整Java堆的大小,这会导致它分配进程内存。 Java可以在太阳烧毁之前进行垃圾收集,但是清理是JVM内部的,并且支持它的进程内存不会被返回。
以下评论的详细说明:
用C编写的程序(特别是运行Eclipse的JVM)分配内存的标准方法是调用malloc(3)
,它使用操作系统提供的机制为进程分配内存然后管理个人这些分配中的分配。 malloc()
和free()
如何工作的详细信息是特定于实现的。
在Unix的大多数版本中,进程只获得一个数据段,这是一个连续的内存区域,指向开始和结束的指针。该过程可以通过调用brk(2)
并增加结束指针以分配更多内存或减少它以将其返回到系统来调整此段的大小。 仅可以调整结尾。这意味着,如果malloc()
的实现扩大了数据段,则free()
的相应实现不能缩小它,除非它确定最后没有使用的空间。在实践中,当您malloc()
时,分配有free()
的大量内存很少会在数据段的最后结束,这就是为什么流程会单调增长的原因。