Java 为什么垃圾收集器没有比一位数的无堆%更快地进行更积极的垃圾收集?

Java 为什么垃圾收集器没有比一位数的无堆%更快地进行更积极的垃圾收集?,java,garbage-collection,profiling,Java,Garbage Collection,Profiling,以下是我在WebLogic 11g中的Sun Hotspot 1.6 JVM堆设置: -Xms10g -Xmx10g -XX:MaxPermSize=256m -XX:+UseParNewGC -XX:ParallelGCThreads=2 -XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled -XX:ConcGCThreads=2 我在24小时的JVM堆空闲百分比图中看到的基本上是堆空闲百分比以缓慢的速度下降,直到达到9%左右(大约需要2

以下是我在WebLogic 11g中的Sun Hotspot 1.6 JVM堆设置:

-Xms10g -Xmx10g -XX:MaxPermSize=256m -XX:+UseParNewGC -XX:ParallelGCThreads=2 -XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled -XX:ConcGCThreads=2
我在24小时的JVM堆空闲百分比图中看到的基本上是堆空闲百分比以缓慢的速度下降,直到达到9%左右(大约需要24小时)。然后系统运行看起来像一个完整的gc,并返回到97%

我是否应该添加/修改一些设置,告诉JVM在堆空闲率低于10%时更快地完成这个完整的GC?e、 g.一些比率设置


它不会造成问题,它会一直等到9%的空闲时间,但它会使监控/警报变得更加困难。理想情况下,我们希望在任何时候都保持高于30%的空闲率,这样,如果我们降低到这些个位数,我们就知道存在某种问题,例如内存泄漏

如何删除:-Xms10g,然后监视堆的总大小?这也会导致gc运行得更频繁


如果你的应用程序只使用300MB内存(3%),那么从10GB的分配开始似乎是极端的。

结合其他stackoverflow文章找到了答案

-XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=N

其中,N大约是占用的百分比将触发完整GC。默认值是92,这就是为什么我看到完整GC的9%免费。对于我的用例来说,将其切换到65是有效的。完全GC现在大约有35%是免费的。

根据我对java垃圾收集的理解,如果需要,它可以在需要时免费收集。您可以调用system.gc手动告诉垃圾收集器您有应该释放的内容,但gc不必这样做。您可以使用命令system.gc()手动进行垃圾收集。您需要查看完整gc后使用/释放的内存量。否则,可用空间对监视没有用处。
System.gc()
不会最终运行垃圾收集器,它会建议运行垃圾收集器。这不是确定性的。@在最佳实践中,我建议您更多地思考这个问题的原因-我认为您做出了一个错误的假设,即堆的可用空间<30%表示内存泄漏。如果您给JVM X一定数量的堆空间,它将倾向于使用尽可能多的堆-据JVM所知,您可以使用最多
10G
的空间。泄漏的更好指示是当完整的地面军事系统无法回收空间时,或者随着时间的推移回收的空间越来越少,这不容易自动监控。机箱上有128GB的ram。也可以使用10GB堆运行。有时,拉入应用程序的数据相当大(以GB为单位),因此我们需要额外的开销。我们从默认堆大小开始,然后对其进行调整,以考虑某些用例上的OutOfMemory错误。所以10gb的最大容量保持不变。我不想建议您更改最大设置。我在评论-Xms10G,意思是:从分配10g开始。如果没有这一点,堆将开始变小,然后在需要时增长到10g。这将使内存使用监控更加容易