有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java Eclipse发布堆返回系统

我在大量大型项目中使用Eclipse 3.6和Linux上最新的Sun Java 6(64位)。在某些特殊情况下(例如SVN更新),Eclipse需要高达1GB的堆。但大多数情况下,它只需要350MB。当我启用“堆状态”面板时,大多数情况下我都会看到:

350米878米

我用以下设置启动Eclipse:-Xms128m-Xmx1024m

所以大部分时间,大量的MB只是被浪费了,而且在内存使用率很短时间达到峰值时很少被使用。我一点也不喜欢这样,我希望Eclipse将内存释放回系统,以便我可以将其用于其他程序

当Eclipse需要更多内存,而没有足够的可用RAM,Linux无法替换其他正在运行的程序时,我可以接受这一点。我听说有一个-XX:MaxHeapFreeRatio选项。但我从来没有弄明白我必须使用什么样的价值观才能让它起作用。我尝试过的任何价值都没有改变

那么,我如何告诉Eclipse(或Java)释放未使用的堆呢


共 (3) 个答案

  1. # 1 楼答案

    Java的堆不过是JVM进程堆空间中管理的一个大数据结构。这两个堆在逻辑上是独立的实体,即使它们占用相同的内存

    JVM受制于主机系统的malloc()实现,它使用brk()从系统分配内存。在Linux系统(Solaris也是如此)上,分配给进程堆的内存几乎永远不会返回,这主要是因为它变得支离破碎,堆必须是连续的。这意味着分配给进程的内存将单调增加,而保持较小大小的唯一方法是不首先分配内存

    -Xms-Xmx告诉JVM如何提前调整Java堆的大小,这会导致JVM分配进程内存。Java可以进行垃圾收集,直到太阳熄灭,但这种清理是JVM内部的,支持它的进程内存不会返回


    根据以下评论进行详细阐述:

    用C编写的程序(尤其是运行Eclipse的JVM)分配内存的标准方法是调用malloc(3),它使用操作系统提供的机制为进程分配内存,然后在这些分配中管理单个分配。关于malloc()free()如何工作的细节是具体实现的

    在大多数Unix版本中,进程只会获得一个数据段,这是一个连续的内存区域,有指向开始和结束的指针。进程可以通过调用brk(2)并增加结束指针以分配更多内存,或减少结束指针以将其返回系统来调整此段的大小只有末端可以调整。这意味着,如果malloc()的实现放大了数据段,那么free()的相应实现无法缩小数据段,除非它确定末尾有未使用的空间。实际上,分配给malloc()的大量内存在free()数据段时,很少会在数据段的最末端结束,这就是进程趋向于单调增长的原因

  2. # 2 楼答案

    找到了解决办法。我将Java转换为使用G1垃圾收集器,现在HeapFreeRatio参数按预期工作。所以我在eclipse中使用这些选项。伊尼:

    -XX:+UnlockExperimentalVMOptions
    -XX:+UseG1GC
    -XX:MinHeapFreeRatio=5
    -XX:MaxHeapFreeRatio=25
    

    现在,当Eclipse为一个复杂的操作占用超过1GB的RAM,并在垃圾收集后切换回300MB时,内存实际上会释放回操作系统

  3. # 3 楼答案

    你可以去Preferences -> General查看Show heap status。这将在Eclipse的角落中激活堆的良好视图。比如:

    alt text

    如果单击垃圾箱,它将尝试运行垃圾收集并返回内存