如果Java堆内存限制与kubernetes中的pod资源限制不同怎么办?

时间:2018-10-16 17:55:07

标签: java kubernetes heap-memory

我在具有以下配置的吊舱内运行弹簧靴。

广告位限制:

resources:
    limits:
      cpu: "1"
      memory: 2500Mi
    requests:
      cpu: "1"
      memory: 2500Mi

命令参数:

spec:
containers:
- args:
  - -c
  - ln -sf /dev/stdout /var/log/access.log;java -Dcom.sun.management.jmxremote
    -Dcom.sun.management.jmxremote.port=1099 -Dcom.sun.management.jmxremote.authenticate=false
    -Dcom.sun.management.jmxremote.ssl=false -Djava.security.egd=file:/dev/./urandom
    -Xms1600m -Xmx1600m -XX:NewSize=420m -XX............
  1. 如果Java进程已达到其最大堆限制(即1600m(Xmx1600m)),会发生什么情况
  2. 如果Xmx对pod内的Java进程没有影响,则它可以上升到pod的右边限制(即内存:limits部分的2500Mi)
  3. 如果以上配置正确,则我们浪费了900Mi的内存权(2500-1600 = 900)

3 个答案:

答案 0 :(得分:3)

-Xmx标志仅控制Java堆内存,该内存是运行代码时可用于您自己的Java对象的空间。如果用完了,JVM将进行垃圾回收以腾出空间。如果仍然用光了,则会抛出OutOfMemoryException。

Java JVM内部还使用了一堆其他内存来进行诸如加载类,JIT编译等工作。因此,您需要在Kubernetes中允许更多的内存,而不仅仅是-Xmx值。如果超过Kubernetes限制值,则Java可能会崩溃。

您在上面发布的配置看起来不错。通常,无限制运行一段时间后,我会通过查看Kubernetes内存使用情况图来找到这些值。

答案 1 :(得分:1)

如果在docker中运行JVM,而不是手动设置-Xmx-Xms选项,则最好使用-XX:+ UnlockExperimentalVMOptions -XX:+ UseCGroupMemoryLimitForHeap告诉JVM遵守容器的限制

请参阅https://hub.docker.com/_/openjdk/ 使JVM遵守CPU和RAM限制以获取更多信息。

答案 2 :(得分:0)

如果Java进程已达到其最大堆限制,则jvm如果无法在GC后重新获得堆内存,则会抛出内存不足错误。在这种情况下,pod将运行,但是Java进程出错。

Xmx对POD内的jvm堆起作用,并且jvm堆不能超过该值。在您的情况下,可能会增加jvm堆,因为pod的内存相对较高。