Home > Software engineering >  how to disable memory calculator from docker image generated by buildpack
how to disable memory calculator from docker image generated by buildpack

Time:12-03

When I'm establishing the memory limits (-Xmx512m -Xms512m) in the deployment.yml for a Spring Boot Application which the docker image was generated with the command (mvn spring-boot:build-image) then I'm receiving the following error:

Setting Active Processor Count to 4
Adding $JAVA_OPTS to $JAVA_TOOL_OPTIONS
unable to calculate memory configuration
all memory regions require 1130933K which is greater than 956052K available for allocation: 
-Xmx512M, 0 headroom, -XX:MaxDirectMemorySize=10M, -XX:MaxMetaspaceSize=94645K, -XX:ReservedCodeCacheSize=240M,
-Xss1M * 250 threads ←[31;1mERROR: ←[0mfailed to launch: exec.d: failed to execute exec.d file
at path '/layers/paketo-buildpacks_bellsoft-liberica/helper/exec.d/memory-calculator': exit status 1

Current deployment.yml config:

      env:
        - name: SPRING_PROFILES_ACTIVE
          value: prod
        - name: JAVA_OPTS
          value: >-
                -XX: PrintGCDetails
                -Xlog:gc
                -XX: UseParallelGC
                -XX: PrintFlagsFinal
                -Xmx512m
                -Xms512m
      resources:
          requests:
            cpu: 1554m
            memory: 979M
          limits:
            cpu: 1554m
            memory: 979M

How to set the memory limits properly or disable the buildpack memory calculator?

NOTE: I'm using JAVA 11.

CodePudding user response:

You're getting the error:

all memory regions require 1130933K which is greater than 956052K available for allocation: 
-Xmx512M, 0 headroom, -XX:MaxDirectMemorySize=10M, -XX:MaxMetaspaceSize=94645K, -XX:ReservedCodeCacheSize=240M,
-Xss1M * 250 threads

which is telling you that you have an invalid memory configuration. The amount of memory that you want to assign to the JVM does not fit within the limits you have put on your container.

There are a number of ways you can fix this:

  1. Increase the container memory limit so that the JVM fits. The error message tells you how much you'd need, 1130933K.

  2. Reduce the amount of memory you're assigning to the JVM so that it fits within the container memory limit. The error message tells you which JVM memory settings are being used, you can override them in JAVA_TOOL_OPTIONS (or JAVA_OPTS, anything added there is included within JAVA_TOOL_OPTIONS) to limit them.

  3. Remove -Xmx512m -Xms512m from JAVA_OPTS and just let the memory calculator generate the largest JVM memory configuration that will fit within the container memory limit you've assigned. You won't get that much heap, but you'll get as large of a heap as possible within the given container memory limit.

Some notes on these options:

  1. If you try option #2, be careful in terms of what you reduce. The JVM is memory-hungry, but that's also how it's so fast. Make sure you are performance testing before and after any changes you make to ensure that you're not hurting your application performance (or to confirm that you're still performing to required levels).

  2. With the Paketo Java buildpack, you should really never set -Xmx and -Xms. What you want to do instead is to adjust the other memory settings, like -Xss, -XX:ReservedCodeCacheSize=240M, -XX:MaxDirectMemorySize=10M, thread count, etc...

    The memory calculator will adjust the -Xmx and -Xms settings dynamically so that they consume the remainder of the memory in the container. If you manually set these values, what's likely to happen is that you will either cause an error because the values are too large (what happened here) or that you set them too low and the JVM is not using all of the memory available to it. Let the memory calculator do its job and you'll get the optimal settings.

  3. There is no option to disable the memory calculator and I would strongly caution against attempting to do that. The memory calculator is your friend here.

    It's like a compiler for JVM memory settings. It is checking and validating the settings you enter, so it can tell you in advance if there is a problem with your memory configuration. It might be annoying that it complains, but this is far, far better than having your container crash in the middle of the night because it runs out of memory. If it complains, adjust your memory configuration and then rest easy knowing that everything is properly sized to fit in your container.

  4. The memory calculator will by default size your application for a production deployment, optimizing for performance, not low-memory consumption. Again, Java trades higher memory consumption for speed. To do this, it means your container needs at least 1G of RAM.

    There is a Paketo RFC to add a low-memory mode to the memory calculator. This would make it easier to run PoC applications and other low-traffic apps that are willing to accept potentially lower performance in exchange for reducing memory consumption (and thereby cost). This RFC has not been implemented as of this post, but we hope to have it implemented in the near future.

CodePudding user response:

Thank you for your answer. But I applied the second option, I understood your point of view, I will try to do a summary about the approach

Iteration 1: No limits

 env:
            - name: SPRING_PROFILES_ACTIVE
              value: prod
            - name: JAVA_OPTS
              value: >-
                    -Xlog:gc
                    -XX: UseParallelGC

grafana visualization it1

Memory Calculator:

Calculating JVM memory based on 13287832K available memory
Calculated JVM Memory Configuration: -XX:MaxDirectMemorySize=10M -Xmx12681764K -XX:MaxMetaspaceSize=94067K -XX:ReservedCodeCacheSize=240M -Xss1M (Total Memory: 13287832K, Thread Count: 250, Loaded Class Count: 14194, Headroom: 0%)
Enabling Java Native Memory Tracking
Adding 128 container CA certificates to JVM truststore
Spring Cloud Bindings Enabled
Picked up JAVA_TOOL_OPTIONS: -Djava.security.properties=/layers/paketo-buildpacks_bellsoft-liberica/java-security-properties/java-security.properties -XX: ExitOnOutOfMemoryError -XX:ActiveProcessorCount=4 -Xlog:gc -XX: UseParallelGC -XX:MaxDirectMemorySize=10M -Xmx12681764K -XX:MaxMetaspaceSize=94067K -XX:ReservedCodeCacheSize=240M -Xss1M -XX: UnlockDiagnosticVMOptions -XX:NativeMemoryTracking=summary -XX: PrintNMTStatistics -Dorg.springframework.cloud.bindings.boot.enable=true

Xmx12681764K = 1585,2205 MB

In this case, Graphana visualize all resources from the hardware and it is not the ideal configuration so, it is necessary to define limits from the upper boundary, the pod.

Iteration 2: With defined limits at kubernetes level

  env:
    - name: SPRING_PROFILES_ACTIVE
      value: prod
    - name: JAVA_OPTS
      value: >-
            -Xlog:gc
            -XX: UseParallelGC
  resources:
    requests:
      cpu: 1554m
      memory: 979M
    limits:
      cpu: 1554m
          memory: 979M

grafana visualization it2

Memory calculator:

Calculated JVM Memory Configuration: -XX:MaxDirectMemorySize=10M -Xmx349984K -XX:MaxMetaspaceSize=94067K -XX:ReservedCodeCacheSize=240M -Xss1M (Total Memory: 956052K, Thread Count: 250, Loaded Class Count: 14194, Headroom: 0%)
Enabling Java Native Memory Tracking
Adding 128 container CA certificates to JVM truststore
Spring Cloud Bindings Enabled
Picked up JAVA_TOOL_OPTIONS: -Djava.security.properties=/layers/paketo-buildpacks_bellsoft-liberica/java-security-properties/java-security.properties -XX: ExitOnOutOfMemoryError -XX:ActiveProcessorCount=4 -Xlog:gc -XX: UseParallelGC -XX:MaxDirectMemorySize=10M -Xmx349984K -XX:MaxMetaspaceSize=94067K -XX:ReservedCodeCacheSize=240M -Xss1M -XX: UnlockDiagnosticVMOptions -XX:NativeMemoryTracking=summary -XX: PrintNMTStatistics -Dorg.springframework.cloud.bindings.boot.enabl

In this case, Memory Calculator determinates a minimum memory to operate with the application but not limit the upper boundary because it is limited by the configuration from k8s level. My doubt was generated by the delay in the grahana visualization.

As you say, Memory calculator is our side to help.

Many thanks in advance

Alberto.

  • Related