Docker Community Forums

Share and learn in the Docker community.

Why Docker Container State OOMKilled not working properly?

docker

(Qiulei1guo) #1

Tried to explore the OOMKilled, run a simple pretty much Hello World example as below. The container exit as “java.lang.OutOfMemoryError” (50MB), Yet the OOMKilled is always false. Any idea?

Command to run the container

docker run --memory=50m test_oom
Used memory MB: 1
Used memory MB: 2
Used memory MB: 3
Used memory MB: 4
Used memory MB: 5
Used memory MB: 6
Used memory MB: 7
Used memory MB: 8
Used memory MB: 9
Used memory MB: 10
Used memory MB: 11
Used memory MB: 12
Used memory MB: 13
Used memory MB: 14
Used memory MB: 15
Used memory MB: 16
Used memory MB: 17
Used memory MB: 18
Used memory MB: 19
Used memory MB: 20
Used memory MB: 21
Used memory MB: 22
Used memory MB: 23
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
    at TestMemory.main(TestMemory.java:24)

inspect the container, you can see the OOMKilled is false.

 "State": {
            "Status": "exited",
            "Running": false,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 0,
            "ExitCode": 1,
            "Error": "",
            "StartedAt": "2018-10-30T23:09:24.914551185Z",
            "FinishedAt": "2018-10-30T23:09:48.238279487Z"
        },

Dockerfile:

FROM openjdk:8-alpine

ADD testOOM.jar /opt/local/jars/testOOM.jar

CMD ["java", "-jar", "/opt/local/jars/testOOM.jar"]

Java code:

import java.util.LinkedList;
import java.util.List;

/**
 * Test memory.
 */
public class TestMemory {
    static final int oneMB = 1024 * 1024;
    static final long pauseIntervalMilliSec = 1000;
    static final long limitMemoryBytes = 100 * oneMB;

    /**
     * Main function
     * @param args
     */
    public static void main(String[] args) throws InterruptedException {
        List<byte[]> cache = new LinkedList<>();
        Runtime rt = Runtime.getRuntime();
        long usedMemoryBytes = rt.totalMemory() - rt.freeMemory();

        while (usedMemoryBytes < limitMemoryBytes) {
            cache.add(new byte[oneMB]);
            usedMemoryBytes = rt.totalMemory() - rt.freeMemory();
            System.out.println("Used memory MB: " + (usedMemoryBytes / oneMB));

            Thread.sleep(pauseIntervalMilliSec);
        }
    }
}

My docker version:

 Client:
 Version:      17.09.0-ce
 API version:  1.32
 Go version:   go1.8.3
 Git commit:   afdb6d4
 Built:        Tue Sep 26 22:40:09 2017
 OS/Arch:      darwin/amd64

Server:
 Version:      17.09.0-ce
 API version:  1.32 (minimum version 1.12)
 Go version:   go1.8.3
 Git commit:   afdb6d4
 Built:        Tue Sep 26 22:45:38 2017
 OS/Arch:      linux/amd6

(Jjfraney) #2

The application exceeded the jvm memory limitation before it exceeded the container restriction.