我们有linux服务器在java中运行大约200个微服务,使用c-groups隔离cpu和内存隔离。我们发现的一件事是java往往需要一个完整的CPU核心才能有效地执行(主要)垃圾收集。
然而,显然有200个应用程序在运行,只有24个CPU,如果它们同时决定使用GC,它们将受到c-groups的限制。由于典型的应用CPU使用率相对较小(比如1 cpu峰值的约15%),因此找到一种方法可以确保它们不会同时处理所有GC。
我正在调查我们如何安排GC,以便每个微服务器不同时使用GC,这样我们仍然可以为每个主机运行200多个应用程序,但是想知道是否有人在此之前有关于此主题的一些建议或经验试图重新发明轮子。
我发现我们可以使用命令行方法,以及使用MBean来实际触发GC,但是请注意不建议这样做,因为这会搞乱java用于的非确定性过程GC。
我正在考虑的事情是使用性能指标来监控cpu,内存和流量以尝试预测GC,然后如果多个GC即将发生,也许我们可以一次触发一个,但这可能会不切实际或不好主意。
我们正在运行java 7和8。
答案 0 :(得分:0)
您无法安排GC,因为它取决于分配率 - 即它取决于负载和应用程序逻辑。一些垃圾收集器试图控制主要GC持续时间,GC消耗的总时间,而不是速率。也不能保证外部触发的GC(例如通过MBean)将实际运行,如果它将运行,它可能会在稍后运行然后被触发。
正如其他人指出的那样,这是一种非常罕见的可能性(您可以通过收集所有应用程序中主要GC的平均周期数并计算直方图)来计算它,以便在“正常”负载下面对它。在“繁重”负载下,您可能会比增加分配率的可能同时GC更早地面临CPU短缺 - 因为您需要“长”(取决于您的对象的大小)“长” “ - 让对象污染老一代以触发主要的GC。