Refer to this article: https://www.baeldung.com/jvm-compressed-oops

First, let's find out what an oop is:

The HotSpot JVM uses a data structure called oops or Ordinary Object Pointers to represent objects. These oops are equivalent to native C pointers. The instanceOops are a special kind of oop that represents the object instances in Java. Moreover, the JVM also supports a handful of other oops that are kept in the OpenJDK source tree.

Furthermore

A very neat feature is the compressing of oops to 32 bits:

As it turns out, the JVM can avoid wasting memory by compressing the object pointers or oops, so we can have the best of both worlds: allowing more than 4 GB of heap space with 32-bit references in 64-bit machines!

Finally:

To enable oop compression, we can use the -XX:+UseCompressedOops tuning flag. The oop compression is the default behavior from Java 7 onwards whenever the maximum heap size is less than 32 GB. When the maximum heap size is more than 32 GB, the JVM will automatically switch off the oop compression. So memory utilization beyond a 32 Gb heap size needs to be managed differently.

So, the answer to your question is: you simply passed beyond the threshold of 32 GB as the maximum heap size.

Proof

Look at your graphs and see that the behavior we are speaking about happens at the level of 32 GB.

Answer from Lajos Arpad on Stack Overflow
🌐
Oracle
docs.oracle.com › en › java › javase › 17 › gctuning › ergonomics.html
Ergonomics - Java
October 20, 2025 - The maximum pause-time goal is specified with the command-line option -XX:MaxGCPauseMillis=<nnn>. This is interpreted as a hint to the garbage collector that a pause-time of <nnn> milliseconds or fewer is desired. The garbage collector adjusts the Java heap size and other parameters related to garbage collection in an attempt to keep garbage collection pauses shorter than <nnn> milliseconds.
Discussions

java - Increasing the JVM maximum heap size for memory intensive applications - Stack Overflow
I can now set 4096 MB of maximum heap size. When you have both 32 and 64 bits installed, at least on Windows you need to point the Java path for your applications to the new 64 bit version installed. Otherwise, the error will persist. On Windows this often can be done by changing the Java path on system's Environment Variables. 2015-02-02T23:10:09.737Z+00:00 ... I guess the limit for the maximum heap is not 1280, but something near to 1700MB... More on stackoverflow.com
🌐 stackoverflow.com
How is the default max Java heap size determined? - Stack Overflow
If I omit the -Xmxn option from the Java command line then a default value will be used. According to Java documentation "the default value is chosen at runtime based on system configuration&... More on stackoverflow.com
🌐 stackoverflow.com
Java memory usage in containers
You can set JVM initial and max ram percentages like so: -XX:InitialRAMPercentage=80 -XX:MaxRAMPercentage=80 Those flags cause the JVM to consume only that percentage of the pod memory, they were introduced in OpenJDK 10 [1]. This is better than setting Xmx within the docker container because it effectively lets you manage your JVM memory via the pod settings. Gives your k8s team control of actual memory usage. There were some issues with the implementation in JDK 11 which lead to OOMKilled errors (basically the flags were not respected, but that is resolved now). OOMKilled Details: https://factorhouse.io/blog/articles/corretto-memory-issues/ You still need pod level limits for those flags to take effect, but they're pretty useful. When you set your pod memory memory resources you should run with a guaranteed QoS [2] by setting both requested and limit to the same value. Guaranteed QoS means that the pod is least likely to be evicted [3]. resources: limits: memory: 8Gi requests: memory: 8Gi By the way 80% percentage is pretty high, probably safer in the general case to go with 70% cos the remaining memory will be required by the OS. Soure: I work at Factor House (and I wrote that blogpost about OOMKilled errors). We build dev tools for Apache Kafka and Apache Flink (written in Clojure, but runs on the JVM), we offer both an uberjar and a docker container that runs the uberjar as deployment methods, so we have a bit of experience tuning this stuff. [1] https://bugs.openjdk.org/browse/JDK-8146115 [2] https://kubernetes.io/docs/tasks/configure-pod-container/quality-service-pod/#create-a-pod-that-gets-assigned-a-qos-class-of-guaranteed [3] https://kubernetes.io/docs/concepts/workloads/pods/pod-qos/#guaranteed More on reddit.com
🌐 r/java
30
47
September 22, 2024
Increase heap size in Java - Stack Overflow
2019-01-17T20:30:36.307Z+00:00 ... JAVA_OPTS didn't work for me. JAVA_TOOL_OPTIONS did. 2021-07-27T01:44:46.483Z+00:00 ... Save this answer. ... Show activity on this post. It is possible to increase heap size allocated by the JVM by using these command line options: -Xms set initial Java heap size -Xmx set maximum ... More on stackoverflow.com
🌐 stackoverflow.com
🌐
Delcastanher
delcastanher.github.io › posts › java 17 heap space
Java 17 Heap Space | Delcastanher's Memory Allocation
July 11, 2023 - The heap is created when the Java Virtual Machine starts up and may increase or decrease in size while the application runs. 2 · These are heap size default selections: Initial heap size of 1/64 of physical memory; Maximum heap size of 1/4 of physical memory.
🌐
Linux.org
linux.org › home › forums › general linux forums › general computing
How to increase Java runtime maximum heap memory? | Linux.org
December 1, 2024 - VM settings: Max. Heap Size (Estimated): 3.86G Using VM: OpenJDK 64-Bit Server VM · Click to expand... This according to my understanding means that Java applications will be limited to 4GB of memory, however my system has 16GB and I want to increase it to at least 8GB because I need it for a game.
🌐
W3Docs
w3docs.com › java
How is the default max Java heap size determined?
For systems with 1 GB or more of physical memory, the default maximum heap size is set to 1/4 of the physical memory up to a maximum of 1 GB.
🌐
GeeksforGeeks
geeksforgeeks.org › java › how-is-the-default-max-java-heap-size-determined
How is the default max Java Heap size determined? - GeeksforGeeks
July 23, 2025 - The default maximum heap size is half of the physical memory up to a physical memory size of 192 megabytes and otherwise one-fourth of the physical memory up to a physical memory size of 1 gigabyte.
🌐
Alvin Alexander
alvinalexander.com › blog › post › java › java-xmx-xms-memory-heap-size-control
How to control Java heap size (memory) allocation (xmx, xms) | alvinalexander.com
January 31, 2026 - In my case I didn’t think about it too hard and just chose a heap size limit of 64 MB RAM, and after I set this RAM limit my program ran fine. You set the maximum Java heap size of your program using the -Xmx option to the Java interpreter.
Find elsewhere
🌐
Oracle
docs.oracle.com › cd › E19159-01 › 819-3681 › abeii › index.html
Tuning the Java Heap (Sun Java System Application Server 9.1 Performance Tuning Guide)
By default, the JVM grows or shrinks the heap at each GC to try to keep the proportion of free space to the living objects at each collection within a specific range. This range is set as a percentage by the parameters -XX:MinHeapFreeRatio=minimum and -XX:MaxHeapFreeRatio=maximum; and the total size bounded by -Xms and -Xmx.
🌐
Baeldung
baeldung.com › home › java › jvm › guide to the most important jvm parameters
Guide to the Most Important JVM Parameters | Baeldung
January 8, 2024 - We can mark units as ‘g’ for GB, ‘m’ for MB, and ‘k’ for KB. For example, if we want to assign minimum 2 GB and maximum 5 GB to JVM, we need to write: ... Starting with Java 8, the size of Metaspace isn’t defined.
🌐
IBM
ibm.com › docs › en › webmethods-integration › wm-universal-messaging › 11.1.0
Configuring the JVM Heap Size and Direct Memory - IBM Documentation
March 12, 2026 - wrapper.java.additional.17=-XX:MaxDirectMemorySize=512m ... The default value in the Server_Common.conf file is 1G (1 gigabyte). Restart the server for the changes to take effect.
🌐
Azul
docs.azul.com › prime › Heap-Size
Recommended Heap Size
The default value is 1.5625% of the total system memory or cgroup/container limit, and ranges from a minimum 128 MB to a maximum 2 GB. When ZST is installed, this parameter is ignored and the minimum heap size is equal to -Xmx, except when heap elasticity is enabled.
🌐
IBM
ibm.com › docs › en › was-nd › 8.5.5
Modifying the JVM heap size - IBM Documentation
February 9, 2026 - The default maximum heap size value is 256 MB. ... The heap size that you define in the dynamic cluster template is configured on each server in the dynamic cluster. If the server and application placement controller are on the same node, the ...
🌐
Jenkins
jenkins.io › blog › 2026 › 02 › 06 › tuning-java-settings-for-higher-performance
Tuning Jenkins Java Settings For Responsiveness and Stability with Large Instances
February 6, 2026 - Before diving into configuration, ... predictable and low. It’s the default for Java 17+ and works well for heaps from 4GB to 40GB....
Top answer
1 of 10
669

On Windows, you can use the following command to find out the defaults on the system where your applications runs.

java -XX:+PrintFlagsFinal -version | findstr HeapSize

Look for the options MaxHeapSize (for -Xmx) and InitialHeapSize for -Xms.

On a Unix/Linux system, you can do

java -XX:+PrintFlagsFinal -version | grep HeapSize

I believe the resulting output is in bytes.

2 of 10
130

For Java SE 5: According to Garbage Collector Ergonomics [Oracle]:

initial heap size:

Larger of 1/64th of the machine's physical memory on the machine or some reasonable minimum. Before J2SE 5.0, the default initial heap size was a reasonable minimum, which varies by platform. You can override this default using the -Xms command-line option.

maximum heap size:

Smaller of 1/4th of the physical memory or 1GB. Before J2SE 5.0, the default maximum heap size was 64MB. You can override this default using the -Xmx command-line option.

UPDATE:

As pointed out by Tom Anderson in his comment, the above is for server-class machines. From Ergonomics in the 5.0 JavaTM Virtual Machine:

In the J2SE platform version 5.0 a class of machine referred to as a server-class machine has been defined as a machine with

  • 2 or more physical processors
  • 2 or more Gbytes of physical memory

with the exception of 32 bit platforms running a version of the Windows operating system. On all other platforms the default values are the same as the default values for version 1.4.2.

In the J2SE platform version 1.4.2 by default the following selections were made

  • initial heap size of 4 Mbyte
  • maximum heap size of 64 Mbyte
🌐
Reddit
reddit.com › r/java › java memory usage in containers
r/java on Reddit: Java memory usage in containers
September 22, 2024 -

Ok, so my company has a product that was recently moved to the cloud from old bare metal. The core is the legacy app, the old monolith. A lot of care has been taken for that one, as such I'm not worried about it. However there are a bunch of new micro-services added around it that have had far less care.

The big piece that I'm currently worried about is memory limits. Everything runs in Kubernetes, and there are no memory limits on the micro service pods. I feel like I know this topic fairly well, but I hope that this sub will fact check me here before I start pushing for changes.

Basically, without pod memory limits, the JVM under load will keep trying to gobble up more and more of the available memory in the namespace itself. The problem is the JVM is greedy, it'll grab more memory if it thinks memory is available to keep a buffer above what is being consumed, and it won't give it up.

So without pod level limits it is possible for one app to eat up the available memory in the namespace regardless of if it consistently needs that much. This is a threat to the stability of the whole ecosystem under load.

That's my understanding. Fact check me please.

Top answer
1 of 5
40
You can set JVM initial and max ram percentages like so: -XX:InitialRAMPercentage=80 -XX:MaxRAMPercentage=80 Those flags cause the JVM to consume only that percentage of the pod memory, they were introduced in OpenJDK 10 [1]. This is better than setting Xmx within the docker container because it effectively lets you manage your JVM memory via the pod settings. Gives your k8s team control of actual memory usage. There were some issues with the implementation in JDK 11 which lead to OOMKilled errors (basically the flags were not respected, but that is resolved now). OOMKilled Details: https://factorhouse.io/blog/articles/corretto-memory-issues/ You still need pod level limits for those flags to take effect, but they're pretty useful. When you set your pod memory memory resources you should run with a guaranteed QoS [2] by setting both requested and limit to the same value. Guaranteed QoS means that the pod is least likely to be evicted [3]. resources: limits: memory: 8Gi requests: memory: 8Gi By the way 80% percentage is pretty high, probably safer in the general case to go with 70% cos the remaining memory will be required by the OS. Soure: I work at Factor House (and I wrote that blogpost about OOMKilled errors). We build dev tools for Apache Kafka and Apache Flink (written in Clojure, but runs on the JVM), we offer both an uberjar and a docker container that runs the uberjar as deployment methods, so we have a bit of experience tuning this stuff. [1] https://bugs.openjdk.org/browse/JDK-8146115 [2] https://kubernetes.io/docs/tasks/configure-pod-container/quality-service-pod/#create-a-pod-that-gets-assigned-a-qos-class-of-guaranteed [3] https://kubernetes.io/docs/concepts/workloads/pods/pod-qos/#guaranteed
2 of 5
34
Ensure you're running on Java 17 and then set either Xmx and Xms or go the "MaxRAM" route - there are pros and cons to each approach. You should research both, this is a reasonable start: https://www.baeldung.com/java-xmx-vs-maxram-jvm
🌐
Blogger
javarevisited.blogspot.com › 2013 › 04 › what-is-maximum-heap-size-for-32-bit-64-JVM-Java-memory.html
What is the maximum Heap Size of 32 bit or 64-bit JVM in Windows and Linux?
Windows reserves some space for his own and seems also allocate memory around half of memory address bar, which consequently reduces contiguous memory space somewhere less than 2GB, around 1500 to 1600M and when you give more than this size, ...
🌐
Reddit
reddit.com › r/java › jvm (total) max memory
r/java on Reddit: JVM (total) max memory
June 10, 2023 -

I was pondering it for a while now and... it would be great if JVM would allow specifying maximum (total) JVM memory usage.

Currently, we can specify it for various parts of JMV (most notably heap) but very often other parts (meta, threads, code, gc, symbols, etc) take also part of memory (often significant) thus specifying only heap can be tricky, especially if we want to maximize resource usage on the machine (be that VM or within container)...

Top answer
1 of 5
10
Yes, from a developer point of view, that would be easier. It's probably because its complex memory management model that this is not possible. What I mostly do is: Pack the Java application in a container (so you know it's the only running process). Set the memory limit on the container level. For example, attribute 4 GB max to the container. Start the container with -XX:MaxRAMPercentage=80.0 (this leaves enough room for other types of memory and OS processes. The above is probably a bit on the safe side, so when you monitor your application a bit longer, it may be safe to put the MaxRamPercentage value a bit higher.
2 of 5
2
I highly recommend reading the Measuring Performance article from the Quarkus team. They touch on what metric to look at in order to capture the entire, actual memory usage of a JVM process. If you‘re using Micrometer, you can include RSS metrics via https://github.com/mweirauch/micrometer-jvm-extras . Micrometer ships with metrics for Heap and Non-Heap usage out of the box. You should monitor heap, non-heap, and RSS of your application under load to get an idea what a sensible MaxRAMPercentage might be. We ran with MaxRAMPercentage=90.0 and were experiencing OOMKilled issues on k8s, despite our Heap metrics staying well below the memory limit configured in our deployment. It turned out that we used a compression library that essentially was just a JNI binding to a native library, and it was buffering large amounts of data off-heap.