14

According to this link, there is an option to set MaxRamSize manually to restrict the JVM to not use memory beyond this. But I have not seen any documentation of the same. I've never known this. Is there anything like this or anything similar? PS. I know and I'm not looking to set heap/stack/metaspace/native memory sizes. I just would like to know if there is an overall memory limiting option.

Trying it did not help as It errored out:

Improperly specified VM option 'MaxRAM=1073741824B'
Could not create the Java Virtual Machine.
A fatal exception has occurred. Program will exit.

Infact according to this link open-jdk seems to have these options. Another link that I found I believe points to set the heap size. Which again is not looking for. But this is for Oracle I guess.

Why I'm looking for this kind of an option to run the application inside a container (Like Docker) and prevent the application from being killed by the OOM Killer. What I believe is if there is a setting of such the java application would error or crash with a java.lang.OutOfMemoryError rather, than the container being terminated.

My assumptions and understandings may be totally wrong. This question may also be totally wrong and irrelevant. But of course, asking is the way forward :).

Vipin Menon
  • 2,039
  • 3
  • 11
  • 18

3 Answers3

7

Why I'm looking for this kind of an option to run the application inside a container (Like Docker) and prevent the application from being killed by the OOM Killer.

This is exactly the option you are looking for. Moreover, it was properly integrated with cgroups (~docker) as part of JDK-8170888. Note that this flag does not prevent JVM from allocating more memory than its value, but rather gives a hint "I know my physical RAM limit is X, please allocate within X", so JVM will share this value between Java heap and native memory. But if e.g. your application has native memory leak or classloader leak, then this limit will be reached anyway.

JVM is complaining on MaxRAM=1073741824B because it doesn't expect B in the end, it should be declared as -XX:MaxRAM=1073741824. See the description of the flag: Real memory size (in bytes) used to set maximum heap size.

qwwdfsad
  • 2,709
  • 13
  • 23
  • 1
    Yes, both flags work . As in the JVM takes them. Unfortunately, running the application under stress/load says a different story.... I see NMT stats still spiking memory above MAXRam and eventually the OOM Killer kicking in. Neither of the flags seem to restrict the JVM from consuming more than the limited amount for the container. – Vipin Menon Sep 26 '18 at 06:47
  • Also as suggested in [JDK-8170888](https://bugs.openjdk.java.net/browse/JDK-8170888) is this only for heap?? – Vipin Menon Sep 26 '18 at 06:52
  • It's indeed the size of the heap, but slightly adjusted using (one more) flag `MaxHeapSize`. It doesn't constraint runtime from consuming more memory (it's not so easy to do so consistently), but rather a hint to runtime. – qwwdfsad Sep 26 '18 at 08:30
  • If you see unexpected spikes, I'd recommend you to track application native memory with -XX:NativeMemoryTracking=“...” – qwwdfsad Sep 26 '18 at 08:31
3

I found the reference

https://chriswhocodes.com/hotspot_options_jdk11.html?s=MaxRam

But as Stephen C suggests it is probably just the B

NOTE: This is the maximum RAM size used to calculate the default Heap and Direct memory maximum. It doesn't provide a greater enforcement.

Real memory size (in bytes) used to set maximum heap size

and for another parameter

Maximum ergonomically set heap size (in bytes); [the default] zero means use MaxRAM * MaxRAMPercentage / 100


In the Oracle/OpenJDK there is no obvious option.

$ java -XX:+PrintFlagsFinal -version | grep -i MaxRAM

However, on Linux you can set the maximum memory size with ulimit however this will hard crash the JVM if reached.

Aleksandr Kravets
  • 5,360
  • 7
  • 50
  • 66
Peter Lawrey
  • 498,481
  • 72
  • 700
  • 1,075
  • I feel the same. But I dunno – Vipin Menon Sep 25 '18 at 10:13
  • 1
    It's because you should grep for `MaxRAM` :) – qwwdfsad Sep 25 '18 at 13:07
  • End of the day, -XX:MaxRAM Did not prevent OOM Killier killing the application process. – Vipin Menon Oct 05 '18 at 08:08
  • @VipinMenon agreed, it only sets the value used for further calculation. It is not enforced in itself. Using `ulimit` will result in the process dying without the OOM killer being invoked. – Peter Lawrey Oct 05 '18 at 08:12
  • If you want to limit resident memory on Linux with `ulimit` (RLIMIT_RSS) then it doesn't have any effect: https://linux.die.net/man/2/prlimit ulimit can only limit the virtual memory (RLIMIT_AS) but that' of little use. – Juraj Martinka Aug 07 '20 at 19:52
3

I think java is complaining about the "B". According to the manual entry, the java command understands k / K or m / M or g / G suffixes for sizes. It doesn't mention "B".

(Did you notice that the error message says "improperly specified", not "unknown"? That hints that the java command has recognized the option, but the syntax is incorrect. See above ...)

Looking at the OpenJDK source code for Java 11, I can see a MaxRAM parameter defined in the "gc_globals.hpp" file.

Stephen C
  • 632,615
  • 86
  • 730
  • 1,096