Search code examples
kubernetesjvm

UseContainerSupport and direct memory


In a container-based environment such as Kubernetes, the UseContainerSupport JVM feature is handy as it allows configuring heap size as a percentage of container memory via options such as XX:MaxRAMPercentage instead of a static value via Xmx. This way you don't have to potentially adjust your JVM options every time the container memory limit changes, potentially allowing use of vertical autoscaling. The primary goal is hitting a Java OufOfMemoryError rather than running out of memory at the container (e.g. K8s OOMKilled).

That covers heap memory. In applications that use a significant amount of direct memory via NIO (e.g. gRPC/Netty), what are the options for this? The main option I could find is XX:MaxDirectMemorySize, but this takes in a static value similar to Xmx.


Solution

  • There's no similar switch for MaxDirectMemorySize as far as I know. But by default (if you don't specify -XX:MaxDirectMemorySize) the limit is same as for MaxHeapSize. That means, if you set -XX:MaxRAMPercentage then the same limit applies to MaxDirectMemory.

    Note: that you cannot verify this simply via -XX:+PrintFlagsFinal because that prints 0:

    java -XX:MaxRAMPercentage=1 -XX:+PrintFlagsFinal  -version  | grep 'Max.*Size'
    ...
     uint64_t MaxDirectMemorySize                      = 0                                         {product} {default}
       size_t MaxHeapSize                              = 343932928                                 {product} {ergonomic}
    ...
    openjdk version "17.0.2" 2022-01-18
    ...
    

    See also https://dzone.com/articles/default-hotspot-maximum-direct-memory-size and Replace access to sun.misc.VM for JDK 11

    My own experiments here: https://github.com/jumarko/clojure-experiments/pull/32