Search code examples
javajava-8jvmcgroups

cgroup v2 and java 8


We ran into a problem all of a sudden after switching our base jdk images and an upgrade of k8s, specifically we wanted to use eclipse-temurin:8u312-b07-jdk. Here is a very simplified example:

kubectl run jdk --image eclipse-temurin:8u312-b07-jdk --limits "memory=2Gi"
kubectl exec jdk -it -- /bin/bash
nano Dummy.java

with content:

import java.util.concurrent.locks.LockSupport;
import java.util.concurrent.TimeUnit;
public class Dummy {
   public static void main(String[] args) throws Exception {
       while(true) {
           LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(1));
       }
   }
}

compile and run it:

javac Dummy.java
java -XX:+UnlockExperimentalVMOptions  -XX:+UseCGroupMemoryLimitForHeap Dummy

And we get a warning:

OpenJDK 64-Bit Server VM warning: Unable to open cgroup memory limit file /sys/fs/cgroup/memory/memory.limit_in_bytes (No such file or directory)

well, yes. There is no such file, but there is cat /sys/fs/cgroup/memory.max (cgroup v2).

Does that mean that UseCGroupMemoryLimitForHeap will have no effect? It surely looks like it. I know it is deprecated and removed in 11 - that's not the point.

Thank you.


I did find this issue and it looks like I can do:

java -XX:+UnlockExperimentalVMOptions -XX:MaxRAM=$(cat /sys/fs/cgroup/memory.max)  Dummy

but that is something I do not really like.


Solution

  • It's for sure something I do not like, but for images that have a cgroup v2, it seems like I will start it with:

    -XX:MaxRAM=$(cat /sys/fs/cgroup/memory.max)
    

    This way, running:

    java -XX:MaxRAMPercentage=50.0
         -XX:InitialRAMPercentage=50.0
         // we don't use this one, but just to look at he resident memory
         -XX:+AlwaysPreTouch
         -XX:MaxRAM=$(cat /sys/fs/cgroup/memory.max) 
         Dummy
    

    will show top -o %MEM as 1GB. Not ideal, but works.