Java堆空间-Xmx究竟是如何工作的?

Java堆空间-Xmx究竟是如何工作的?,java,heap,out-of-memory,Java,Heap,Out Of Memory,我在我的应用程序中遇到了臭名昭著的OutOfMemoryException,我没有简单地增加可用的堆空间,而是试图研究问题所在,以防万一,我的应用程序出现了某种泄漏 我添加了JVM参数-XX:+heapdumponotofmemoryError,当遇到OutOfMemory错误时,它会创建一个堆转储。然后,我分析了使用不同的分析工具生成的转储文件。然后我开始使用-Xmx参数并观察模式 让我困惑的是以下几点。为什么在分析转储时,我发现所有对象的总大小远远小于我使用-Xmx参数设置的总大小? 例如,

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

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

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

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


这是一篇关于的好文章(我找不到更新的,但我认为基础知识仍然适用于较新的虚拟机)。

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

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

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


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

您是否检查了OOME是否确实提到了堆内存?有一些(相对不常见的)抛出OOME的情况,但堆不是满的。对了,@Joachim,JVM x86中太多线程也会崩溃,OOM异常可能很有趣。。。。是的,我犯的错误是这个。试试看,你知道。将返回结果。使用了-XX:MaxPermSize,此后一直存在问题。我认为,我的应用程序中的最新更改已导致阈值被超过,这导致了异常。谢谢你的帮助。