Can the JVM max heap size be dynamic?
Asked Answered
C

4

28

The JVM -Xmx argument lets one set the max heap size for the JVM to some value. But, is there a way to make that value dynamic? In other words, I want to tell the JVM "look, if you need it, just keep taking RAM from the system until the system is out."

Two-part reason for asking: First, the app in question can use a really wide range of ram depending on what the user is doing, so the conceptual min and max values are pretty far apart. Second, it would seem that the JVM reserves the max heap space from virtual memory at boot time. This particular app is run on a pretty wide variety of hardware, so picking a "one-size-fits-all" max heap space is hard since it has to be low enough to run on low-end hardware, but we'd really like to be able to take advantage of really beefy machines if they're available.

Cosenza answered 12/8, 2010 at 22:42 Comment(6)
Possible duplicate: #763795Guelders
And related to: #2074369Guelders
The difference from those questions is in intent; I don't want anything to do with it myself, I really just want the JVM do magically do it for me. :)Cosenza
Well, the JVM does some "magic" based on the system memory available, if you choose the default. download.oracle.com/javase/6/docs/technotes/guides/vm/…Guelders
For reference here is the RFE for hotspot: bugs.sun.com/bugdatabase/view_bug.do?bug_id=4408373Mccready
No... That's far too sensible and flexible an idea. Why do something useful like that when Java can make you guess up front?Panzer
W
14

But, is there a way to make that value dynamic?

Literally, no. The max heap size is set at JVM launch time and cannot be increased.

In practice, you could just set the max heap size to as large as your platform will allow, and let the JVM grow the heap as it needs. There is an obvious risk in doing this; i.e. that your application will use all of the memory and cause the user's machine to grind to a halt. But that risk is implicit in your question.

EDIT

It is worth noting that there are various -XX... GC tuning options that allow you to tweak the way that the JVM expands the heap (up to the maximum).

Another possibility is to split your application into 2 parts. The first part of the application does all of the preparation necessary to determine the "size" of the problem. Then it works out an appropriate max heap size, and launches the memory hungry second part of the application in a new JVM.

  • This only works if the application can sensibly be partitioned as above.

  • This only works if it is possible to compute the problem size. In some cases, computing the problem size is tantamount to computing the result.

  • It is not clear that you will get better overall performance than if you just let the heap grow up to a maximum size.

Worktable answered 12/8, 2010 at 22:54 Comment(3)
I hate to gravedig and all, but could you not create a native library that, in a totally hacky way, adjusts the heap size with realloc & setting the appropriate variables?Aiello
It is impractical. For a start, the Java heap is not allocated out of malloc'd space. If you get past that, you will run into all sorts of complications. If you really wanted the ability to change the max heap size, you would need to modify the JVM / GC. It would be a lot of work.Worktable
"It would be a lot of work." ... and leave you with significant long term technical debt.Worktable
S
7

It doesn't. It could, and it probably should:

-Xmx90%  // 90% of physical memory

However, a default implicit, 100%, is proabbly not a good idea.

A program written in a non-GC language manages its memory very diligently, it will prune any garbage as soon as possible. It makes sense to allow it to get any memory it requests, assuming it's responsible for prompt garbage disposal.

A GC language is different. It collects garbage only when necessary. As long as there's room, it doesn't care about garbage lingering around. If it could get all the memory it would like to have, it would get all the memory in the computer.

So a GC programmer doesn't have to worry about disposing every piece of garbage any more, but he still have to have a general idea of the tolerable garbage/live object ratio, and instruct GC with -Xmx.

Sadesadella answered 12/8, 2010 at 22:49 Comment(3)
Just to add that this limitation is not inherent in GC'd languages, merely a reseult of the questionable implementation Java chosePanzer
The Microsoft Java implementation (way back) did not have the -Xmx concept and could allocate as much memory as was needed.Ideational
It's a bit rude for java to assume it is the only program running, and I don't buy the GC is different. There really is no reason for any language, GC or not, to simply use all available memory. Think it's too hard to dynamically adapt? How about simply running a GC, checking how much memory is 'live', and then when double that memory is used by allocations, run GC again. Problem solved.Mycah
V
3

Basically, you can't adapt to various users' hardware using pure Java: that's when a little bit of shell/batch scripting can come in handy.

I do just that on OS X and Linux: I've got a little bash shell script that takes care of finding the correct JVM parameters depending on the hardware the application is run on and then calling the JVM.

Note that if you're providing a desktop Java application, then you may want to use something like izpack to provide your users an installer:

http://izpack.org

I don't know at all if Java Web Start can be used to provide different JVM parameters depending on the user's config (probably not, and JWS really s*cks big time anyway if you plan to provide a professional looking desktop app).

Vat answered 12/8, 2010 at 23:16 Comment(0)
K
3

There is a JDK Enhancement Proposal (JEP) 8204088

"Dynamic Max Memory Limit"

that suggests to introduce CurrentMaxHeapSize:

To dynamically limit how large the committed memory (i.e. the heap size) can grow, a new dynamically user-defined variable is introduced: CurrentMaxHeapSize. This variable (defined in bytes) limits how large the heap can be expanded. It can be set at launch time and changed at runtime. Regardless of when it is defined, it must always have a value equal or below to MaxHeapSize (Xmx - the launch time option that limits how large the heap can grow). Unlike MaxHeapSize, CurrentMaxHeapSize, can be dynamically changed at runtime.

The expected usage is to setup the JVM with a very conservative Xmx value (which is shown to have a very small impact on memory footprint) and then control how large the heap is using the CurrentMaxHeapSize dynamic limit.

While there are no signs of this feature actively being worked at, it's relatively new JEP (from 2018), so I would still keep this in mind.

And company Jelastic (jelastic.com) has made a working prototype of JEP 8204088 for G1 garbage collector:

See description at http://mail.openjdk.java.net/pipermail/hotspot-gc-dev/2018-May/022077.html and list of patches for OpenJDK http://cr.openjdk.java.net/~tschatzl/jelastic/cmx/

Koopman answered 19/8, 2019 at 19:0 Comment(1)
Nothing significant seems to have happened on this JEP for a few years ...Worktable

© 2022 - 2024 — McMap. All rights reserved.