1

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.

1 Answers1

1

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

Juraj Martinka
  • 3,991
  • 2
  • 23
  • 25
  • I suppose that's as good as we can get. Good to know you've done the homework to make sure that it is indeed following max heap even when that is set by container-based options rather than -Xmx. I will note that I've observed some bigger climbs in overall memory usage under load of my gRPC app, but perhaps there's some native allocations happening that are neither NIO direct buffers nor heap. – Sanjay Vasandani Aug 17 '22 at 21:05
  • For an excellent breakdown of java/jvm app memory usage I really recommend https://stackoverflow.com/questions/53451103/java-using-much-more-memory-than-heap-size-or-size-correctly-docker-memory-limi/53624438#53624438 – Juraj Martinka Aug 18 '22 at 04:39
  • So..what does it mean when we set MaxRAMPercentage=80. The max 80% of memory will be split between heap and non-heap ? – RamPrakash May 26 '23 at 00:01
  • No, that means both heap and direct will be limited to 80% of the available memory (not 40% each). – Juraj Martinka May 26 '23 at 07:12