【问题标题】:Eclipse release heap back to systemEclipse 将堆释放回系统
【发布时间】:2011-04-16 02:50:17
【问题描述】:

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

878M 中的 350M

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

因此,大多数情况下,大量 MB 被浪费了,并且在内存使用量在短时间内达到峰值时很少被使用。我根本不喜欢这样,我希望 Eclipse 将内存释放回系统,以便我可以将其用于其他程序。

当 Eclipse 需要更多内存而没有足够的可用 RAM 而 Linux 无法换出其他正在运行的程序时,我可以接受。我听说有一个 -XX:MaxHeapFreeRatio 选项。但是我从来没有弄清楚我必须使用什么值才能起作用。我尝试过的任何价值都没有产生任何影响。

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

【问题讨论】:

标签: java linux eclipse heap-memory


【解决方案1】:

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

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

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

【讨论】:

    【解决方案2】:

    您可以前往Preferences -> General 并查看Show heap status。这会激活 Eclipse 角落中堆的漂亮视图。像这样的:

    如果你点击垃圾箱,它会尝试运行垃圾收集并返回内存。

    【讨论】:

    • 我知道这个状态显示(甚至在我的问题中提到过),我知道这个垃圾按钮,但它只运行垃圾收集器,不会向系统返回任何内存。因此,如果 Eclipse 有一个 1 GB 的短暂内存使用峰值,那么堆大小将永远保持在 1 GB(直到我重新启动 Eclipse),即使实际只使用了 300 MB 的堆。
    【解决方案3】:

    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() 时在数据段的最后结束,这就是进程倾向于单调增长的原因。

    【讨论】:

    • 这是否意味着这是一个操作系统问题,并且内存在 Windows 上正确返回到系统?关于它在 Linux 上不起作用的声明是否有任何官方消息来源?
    • 这不是操作系统问题。在您的情况下,它是 JVM 为 Java 堆分配多少进程内存、如何释放它以及 JVM 使用的分配器(通常是 libc 的 malloc())如何处理进程内存的组合。我在原始答案中对此进行了详细说明。任何关于特定实现如何表现的“官方声明”都是该实现的来源。
    猜你喜欢
    • 2016-08-05
    • 2019-11-02
    • 1970-01-01
    • 2015-08-08
    • 1970-01-01
    相关资源
    最近更新 更多