我最近发现我的一项服务在垃圾收集中花费了大量时间,因为最大堆大小太小了。该服务在我开始之前就在那里,所以我不知道堆大小很小。如果它超过某个点,我想设置一个警报来警告我,但我也不想给它比它实际需要的更多的资源。您认为对于垃圾收集和堆使用百分比应该警惕的合理水平是多少?
我在想平均堆使用量的警报大约为 85%,gc 为 100 毫秒/5 分钟。
我知道这是基于要求和硬件,但我真的在寻找一些基准或标准来做出决定。
我最近发现我的一项服务在垃圾收集中花费了大量时间,因为最大堆大小太小了。该服务在我开始之前就在那里,所以我不知道堆大小很小。如果它超过某个点,我想设置一个警报来警告我,但我也不想给它比它实际需要的更多的资源。您认为对于垃圾收集和堆使用百分比应该警惕的合理水平是多少?
我在想平均堆使用量的警报大约为 85%,gc 为 100 毫秒/5 分钟。
我知道这是基于要求和硬件,但我真的在寻找一些基准或标准来做出决定。
亚历克斯洛克伍德的回答是这样的:
建议的堆内存使用和 GC 时间的“最大级别”越少越好。
那是误导。我实际上建议相反。尝试压缩堆大小是一个坏主意,因为这将导致您的应用程序更频繁地运行 GC,并且花费更少的时间(平均而言)做有用的工作。
问题基本上是这样的。当 JVM 用完空间来分配对象时,就会运行经典(非并发)GC。然后它遍历非垃圾对象,将它们复制到不同的“空间”。运行 GC 周期的处理器时间很大程度上取决于非垃圾的数量......但它实现的有用工作(它释放的空间量)与heapsize - nongarbage
. 因此,当您压缩堆大小时,您会减少 GC 所做的有用工作量……对于相同的处理器时间消耗。
原来的问题是这样说的:
我在想平均堆使用量的警报大约为 85%,gc 为 100 毫秒/5 分钟。
在绝对级别的 GC CPU 使用率上设置监视器/警报可能没有用。GC 时间将取决于服务器活动以及 GC 效率。您不希望每次服务器繁忙时 GC 警报都会响起。
85% 的平均堆使用率是值得警惕的合理水平,尽管再次将警报设置为固定水平可能会产生过多的错误警报。
另一种方法是使用 JVM 选项设置“GC 所用时间百分比”阈值,并将其与“在 OutOfMemoryException 上杀死 JVM”选项相结合,并在服务器的启动脚本中放置一个自动重启循环。然后监视重新启动。
这完全取决于您编写的上下文和程序。
建议的堆内存使用和 GC 时间的“最大级别”越少越好。