简体   繁体   中英

Why doesn't the JVM use more Heap Memory

I tried to increase my heap memory like this:

-Xmx9g -Xms8g

to be honest, just because I can.

Now I'm wondering, why the JVM doesn't use more of it, and schedules the GC less frequent.

堆使用图

System:
JVM: Java HotSpot(TM) 64-Bit Server VM (24.51-b03, mixed mode)
Java: version 1.7.0_51, vendor Oracle Corporation

Edit:
I want to improve my configuration for a modelling process (throughput beats responsiveness).

The HotSpot JVM in Java 1.7 separates the heap into a few spaces , and the relevant ones for this discussion are:

  • Eden, where new objects go
  • Survivor, where objects go if they're needed after Eden is GC'ed

When you allocate a new object, it's simply appended into the Eden space. Once Eden is full, it's cleaned in what's known as a "minor collection." Objects in Eden that are still reachable are copied to Survivor, and then Eden is wiped (thus collecting any objects that weren't copied over).

What you want is to fill up Eden , not the heap as a whole.

For example, take this simple app:

public class Heaps {
  public static void main(String[] args) {
    Object probe = new Object();
    for (;;) {
      Object o = new Object();
      if (o.hashCode() == probe.hashCode()) {
        System.out.print(".");
      }
    }
  }
}

The probe stuff is just there to make sure the JVM can't optimize away the loop; the repeated new Object() is really what we're after. If you run this with the default JVM options, you'll get a graph like the one you saw. Objects are allocated on Eden, which is just a small fraction of the overall heap. Once Eden is full, it triggers a minor collection, which wipes out all those new objects and brings the heap usage down to its "baseline," close to 0.

So, how do you fill up the whole heap? Set Eden to be very big! Oracle publishes its heap tuning parameters , and the two that are relevant here are -XX:NewSize and -XX:MaxNewSize . When I ran the above program with -Xms9g -XX:NewSize=8g -XX:MaxNewSize=8g , I got something closer to what you expected.

在此输入图像描述

In one run, this used up nearly all of the heap, and all of the Eden space I specified; subsequent runs only took up a fraction of the Eden I specified, as you can see here. I'm not quite sure why this is.

VisualVM has a plugin called Visual GC that lets you see more details about your heap. Here's a screen shot from mine, taken at just the right moment that shows Eden nearly full, while the old space is pretty much empty (since none of those new Object() s in the loop survive Eden collections).

在此输入图像描述

(I'll try to answer the question of "why" from a different angle here.)

Normally you want to balance two things with your GC settings: throughput and responsiveness.

Throughput is determined by how much time is spent doing GC overall, responsiveness is determined by the lengths of the individual GC runs. Default GC settings were determined to give you a reasonable compromise between the two.

High throughput means that measured over a long period of time the GC overhead will be less. High responsiveness on the other hand will make it more likely that a short piece of code will run in more or less the same time and won't be held up for very long by GC.

If you tune your GC parameters to allow the filling of all 9GBs of heap, what you'll find is that the throughput might have increased (although I'm not certain that it always will) but when the GC does eventually run, your application freezes for several seconds. This might be acceptable for a process that runs a single, long-running calculation but not for a HTTP server and even less so for a desktop application.

The moral of the story is: you can tune your GC to do whatever you want but unless you've got a specific problem that you diagnosed (correctly), you're likely to end up worse than with the default settings.

Update: Since it seems you want high throughput but aren't bothered about pauses, your best option is to use the throughput collector (-XX:+UseParallelGC). I obviously can't give you the exact parameters, you have to tune them using this guide by observing the effects of each change you make. I probably don't need to tell you this but my advice is to always change one parameter at a time, then check how it affects performance.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM