Java应用程序未利用完整堆内存

Java应用程序未利用完整堆内存,java,memory,memory-management,heap-memory,Java,Memory,Memory Management,Heap Memory,我使用选项-Xmx20G启动了java应用程序,因此它应该能够使用高达20GB的堆内存。我将jVidualVm和JMC连接到我的应用程序,可以看到应用程序最多只使用8GB内存。 一旦内存使用量达到8GB左右,就会发生垃圾回收 请看图片 内存使用情况如JMC上所示,最大堆内存为20GB 在GC发生之前,您知道为什么内存使用率没有达到20GB左右吗?尝试在命令行中添加–XX:+DisableExplicitGC,以检查这是否会改变某些内容。典型的Java堆分为新空间和旧空间。当新空间填满时,它将被

我使用选项-Xmx20G启动了java应用程序,因此它应该能够使用高达20GB的堆内存。我将jVidualVm和JMC连接到我的应用程序,可以看到应用程序最多只使用8GB内存。 一旦内存使用量达到8GB左右,就会发生垃圾回收

请看图片

内存使用情况如JMC上所示,最大堆内存为20GB


在GC发生之前,您知道为什么内存使用率没有达到20GB左右吗?

尝试在命令行中添加–XX:+DisableExplicitGC,以检查这是否会改变某些内容。

典型的Java堆分为新空间和旧空间。当新空间填满时,它将被垃圾收集。由于“大多数对象死得很早”,而且垃圾比非垃圾“工作更少”,因此新的空间收集器速度很快

在几个新空间集合中幸存下来的对象将移动到旧空间(技术术语为“终身”)。当旧空间开始填满时,会触发旧空间收集器。旧空间收集器速度较慢,因为旧空间通常更大,那里的对象往往能在多个地面军事系统中生存,以及其他因素

所以,看这个图,JVM的新空间是~7GB,旧空间是~14GB。看起来您的应用程序正在稳定地生成垃圾对象,这会反复触发新的空间收集器。然而,看起来新的空间收集器几乎成功地清空了新的空间。(看看图ar4e中的槽有多低。看起来它们下降到了~0.5MB。)


所以简单的回答是,您的20GB堆没有被充分利用。。。因为它不需要被使用。该应用程序/工作负载的大小过大。

尝试了此标志,但没有改变任何内容。记忆中的行为仍然是一样的。我检查了应用程序代码,没有在代码中的任何地方调用System.gc()。我建议使用JConsole更深入地了解内存使用情况。它允许按池查看内存利用率。正如它所暗示的那样,可能是因为你没有足够的长寿命的东西可以保存在老一代。是的。看起来应用程序生成的大多数对象都来自年轻一代。是的,看起来是这样。应用程序生成的大多数对象都来自年轻一代,并使用miner GC收集垃圾。为了证实这一点,我用标志Xmn14G增加了年轻一代的规模。现在使用的内存高达14G。既然我的应用程序中的大多数内存对象都来自年轻一代,那么我是否应该永久性地增加年轻一代的内存大小?它会提高性能吗,因为会发生更少的矿工GC?这是好的做法吗?测量一下!我的直觉是,新空间可能足够大,增加它不会有多大好处。但另一方面,增加新空间可能会增加GC暂停(因为新空间集合是STW),并且它们可能会导致GC过程中出现更多分页(因为新GC必须访问更多页面)。这些都可能是特定于应用程序的。显示GC日志-您很可能会看到较小的GC发生