java
Java-Monitor Forum > Forum > Java Administration » Should we set -Xms to match -Xmx?
Reply
 
Thread Tools Search this Thread Display Modes
  #1  
Old 07-07-2009, 10:55
kjkoster kjkoster is offline
Forum Operator
 
Join Date: Jul 2008
Posts: 1,137
Default Should we set -Xms to match -Xmx?

Dear All,

There is a custom among Java administrators to set -Xms to the same value as -Xmx. I have long wondered what the effect of this could be. Hearsay suggests that this keeps the JVM from repeatedly allocating and de-allocating memory, thus reducing the memory allocation overhead. Unfortunately I have been unable to find any measurements that suggest that doing this makes any difference.

As you may or may not know, Java works with fixed size memory pools. The memory for those pools is allocated by requesting chunks or memory from the operating system.

You can see this in action by watching the memory graphs, where the red line indicates the configured maximum memory to use. The green line shows the actual fill level of the memory pool. The blue line is what Java has requested from the operating system so far. It shows how Java requests and returns memory over time.

Well, I have been running with -Xmx set to 1GB for a long time and recently I figured I would experiment with also setting -Xms to the same value and see for myself what happens. In short, setting -Xms does what it says on the box: it sets the initial memory pool sizes to the value. After that, Java just resumes its normal behaviour of allocating memory. This can be seen in the memory graph below.


As you can see, when we specify -Xms to be the same as -Xmx, the blue line immediately starts out at the maximum level. It stays up there for a while, but after a while the blue line drops sharply. From then on, Java does what is always does: allocate and de-allocate memory from the operating system.

This behaviour seems to be controlled from the PS MarkSweep garbage collector. As you can see in the graph below, Java leaves the committed memory (relatively) untouched, until a full GC is performed. The first PS MarkSweep (which does full garbage collects) spike coincides with the sharp drop in committed memory. In the full GC, it ignores the -Xms setting and returns a large portion of the freed memory to the operating system.


So, to summarise: feel free to keep setting -Xms to match -Xmx if you like. It won't make any difference for a server which runs for longer periods of time.

Kees Jan

PS. Yes, the blue line sometimes crosses up higher than the red line. I don't know why that is, but I believe that Java requests memory in certain fixed size blocks. The crossings may indicate rounding artefacts, where Java decides it is better to ask just a little more so that it can fill an entire block. This is just speculation, tough, so don't take it from me.
Reply With Quote
  #2  
Old 21-07-2009, 14:25
kjkoster kjkoster is offline
Forum Operator
 
Join Date: Jul 2008
Posts: 1,137
Default

Dear All,

As MHSL on #tomcat points out, there should be a difference. The GC tuning guide says it increases predictability of the JVM.

I cannot rhyme that with what I see in my tests, though. The JVM just ignores the -Xms setting after the first full GC. How is that more predictable?

Kees Jan
Reply With Quote
  #3  
Old 22-07-2009, 17:09
guus guus is offline
Junior Member
 
Join Date: Jul 2008
Posts: 14
Send a message via MSN to guus
Default

Interesting find. How do you measure the committed value?

If I hook up jconsole to my Eclipse instance that has Xmx and Xms set to the same value, the 'committed' value (in the textbox on the 'memory' tab) doesn't change at all. It's also identical to the 'max' value.

I've given Eclipse a bit of work to do (cleaning 35 projects, autobuild enabled), which does give me a lot of activity in the memory usage graphs, but still, no changes to the 'committed' value (not even after full GCs). After a period of inactivity, memory usage drops back, and GCs keep the utilization of the heap space at roughly 30%. The reported committed value doesn't change though.
Reply With Quote
  #4  
Old 22-07-2009, 18:39
kjkoster kjkoster is offline
Forum Operator
 
Join Date: Jul 2008
Posts: 1,137
Default

Dear Guus,

I use the values from the memory MBeans. Check the values in the mbeans java.lang:Type=Memory and look at the max, committed and used values.

Hmm. Interesting. What GC does your Eclipse use?

Kees Jan
Reply With Quote
  #5  
Old 24-07-2009, 11:13
guus guus is offline
Junior Member
 
Join Date: Jul 2008
Posts: 14
Send a message via MSN to guus
Default

That MBean shows me slightly different values for max, committed (both 532742144) and init (536870912). Xmx and Xms have been set to 512m. The value for committed doesn't change for me though (not even a little as your graphs show).

This is the JVM I'm using: Java HotSpot(TM) Client VM (14.0-b16, mixed mode, sharing)

The garbage collectors used are the default ones: Copy for the young generation and MarkSweepCompact for the old generation.
Reply With Quote
Reply

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump