最近,我发现我的一项服务在垃圾收集上花费了大量时间,因为最大堆大小太小。该服务在我开始之前就已经存在,因此我没有意识到堆的大小太小。我想发出警报以警告它是否超过某个点,但是我也不想给它超过实际需要的资源。您认为在垃圾回收和已用堆百分比方面应该警惕的合理水平是什么?

我当时在想,平均堆使用率的警报应该是〜85%,以及100 ms的gc / 5分钟。

我知道这是基于需求和硬件的,但是我确实在寻找一些基准或标准来做出决定。

最佳答案

亚历克斯·洛克伍德的答案是这样的:


建议的堆内存使用量和GC时间的“最大级别”越小越好。


那是误导。我实际上建议相反。尝试压缩堆大小是一个坏主意,因为这将导致您的应用程序更频繁地运行GC,并且花费更少的时间(平均)来完成有用的工作。

问题基本上是这样。当JVM用完空间分配对象时,经典(非并行)GC就会运行。然后遍历非垃圾对象,将它们复制到另一个“空间”。运行GC周期的处理器时间最强烈地取决于非垃圾的数量……但是它实现的有用工作(释放的空间量)与heapsize - nongarbage成正比。因此,当压缩堆大小时,对于相同的处理器时间开销,您减少了GC所做的有用工作量。

最初的问题是这样说的:


我当时在想,平均堆使用率的警报应该是〜85%,以及100 ms的gc / 5分钟。


在绝对级别的GC CPU使用率上设置监视器/警报可能没有用。 GC时间将取决于服务器活动以及GC效率。您不希望每次服务器繁忙时都发出GC警报。

平均85%的堆使用率是值得警惕的合理级别,尽管再次将警报设置为固定级别可能会产生过多的错误警报。

替代方法是使用JVM选项设置“在GC中花费的时间百分比”阈值,并将其与“在OutOfMemoryException上杀死JVM”选项结合,然后在服务器的启动脚本中放入自动重新启动循环。然后监视重新启动。

09-10 03:04
查看更多