Java 堆空间 - -Xmx 是如何工作的?
Posted
技术标签:
【中文标题】Java 堆空间 - -Xmx 是如何工作的?【英文标题】:Java Heap Space - How does -Xmx work exactly? 【发布时间】:2011-11-02 23:16:08 【问题描述】:我在我的应用程序中遇到了臭名昭著的 OutOfMemoryException,我没有简单地增加可用的堆空间量,而是试图调查问题所在,以防万一出现某种泄漏从我的应用程序。
我添加了 JVM 参数 -XX:+HeapDumpOnOutOfMemoryError,它在遇到 OutOfMemory 错误时创建一个堆转储。然后我分析了使用不同分析工具生成的转储文件。然后我开始使用 -Xmx 参数并观察模式。
让我感到困惑的是以下内容。为什么在分析转储时我发现所有对象的总大小远小于我使用 -Xmx 参数设置的总大小? 例如,假设我将 -Xmx 设置为“2048m”。当我分析转储文件时,我发现堆上总共有 400Mb 的对象。我期待找到2GB。我错过了什么吗?
【问题讨论】:
您是否检查过您的 OOME 是否确实提到了堆内存?有一些(相对不常见的)OOME 被抛出的情况,但并不是堆满了。 对,@Joachim,JVM x86 中的太多线程也因 OOM 异常而崩溃 【参考方案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 并且从那时起就遇到了问题。我认为我的应用程序中的最新更改导致超过了导致异常的阈值。感谢您的帮助。以上是关于Java 堆空间 - -Xmx 是如何工作的?的主要内容,如果未能解决你的问题,请参考以下文章
优化 Hive 查询。 java.lang.OutOfMemoryError:超出 Java 堆空间/GC 开销限制
OutOfMemoryError 异常:Java 堆空间,如何调试...?
java.lang.OutOfMemoryError:大型Excel文件的Java堆空间[重复]