那么,出现此问题的根源是什么?

1、对于 JVM 而言,如果没有设置 Heap Size,就会按照宿主机环境的内存大小缺省设置自己的最大堆大小。

2、Docker 容器利用 CGroup 对进程使用的资源进行限制,而在容器中的 JVM 依然会利用宿主机环境的内存大小和 CPU 核数进行缺省设置,这导致了 JVM Heap 的错误计算。

同样,类似,JVM 缺省的 GC、JIT 编译线程数量取决于宿主机 CPU 核数。如果我们在一个节点上运行多个 Java 应用,即使我们设置了 CPU 的限制,应用之间依然有可能因为 GC 线程抢占切换,导致应用性能受到影响。

  • - XX : +UnlockExperimentalVMOptions - XX : +UseCGroupMemoryLimitForHeap
  •