【问题标题】:Java Heap Space - How does -Xmx work exactly?Java 堆空间 - -Xmx 是如何工作的?
【发布时间】:2011-11-02 23:16:08
【问题描述】:

我在我的应用程序中遇到了臭名昭著的 OutOfMemoryException,我没有简单地增加可用的堆空间量,而是试图调查问题所在,以防万一出现某种泄漏从我的应用程序。

我添加了 JVM 参数 -XX:+HeapDumpOnOutOfMemoryError,它在遇到 OutOfMemory 错误时创建一个堆转储。然后我分析了使用不同分析工具生成的转储文件。然后我开始使用 -Xmx 参数并观察模式。

让我感到困惑的是以下内容。为什么在分析转储时我发现所有对象的总大小远小于我使用 -Xmx 参数设置的总大小? 例如,假设我将 -Xmx 设置为“2048m”。当我分析转储文件时,我发现堆上总共有 400Mb 的对象。我期待找到2GB。我错过了什么吗?

【问题讨论】:

  • 您是否检查过您的 OOME 是否确实提到了堆内存?有一些(相对不常见的)OOME 被抛出的情况,但并不是堆满了。
  • 对,@Joachim,JVM x86 中的太多线程也因 OOM 异常而崩溃

标签: java out-of-memory heap-memory


【解决方案1】:

我的猜测是,由于现代 GC 将堆划分为单独的内存区域(年轻/终身/永久代),永久代空间完全填满就足以发生内存不足错误。您可以使用各种 JVM 命令行选项来配置不同生成空间的比例。

这是一篇关于 Tuning Garbage Collection with the 5.0 Java[tm] Virtual Machine 的好文章(我找不到更新的文章,但我认为这些基础知识仍然适用于较新的 VM)。

【讨论】:

    【解决方案2】:

    重新阅读您的错误消息 - 它可能会告诉您您用完了哪种类型的内存。我猜这是 PermGen 空间。 Permgen 用于类定义(除其他外)。您可以通过 -XX:MaxPermSize 调整 PermGen 的空间 PermGen 不是堆的一部分,因此不包含在堆转储中。

    有关查看 PermGen 的更多信息,请参阅 this answer

    如果这不是问题,请尝试将您的初始堆大小 (-Xms) 设置为与最大值相同。这样做意味着堆不会增长,这应该使理解发生的事情更容易。

    我建议使用 jvisualvm(JDK 的一部分)来查看程序运行时的内存利用率。

    【讨论】:

    • 可能很有趣....是的,我得到的错误就是这个。试试这个就知道了。将返回结果。
    • 使用了 -XX:MaxPermSize 并且从那时起就遇到了问题。我认为我的应用程序中的最新更改导致超过了导致异常的阈值。感谢您的帮助。
    猜你喜欢
    • 2011-03-06
    • 2017-02-22
    • 2018-08-27
    • 1970-01-01
    • 1970-01-01
    • 2021-09-09
    • 1970-01-01
    • 1970-01-01
    • 2011-10-27
    相关资源
    最近更新 更多