JVM Memory Allocation and what do the Xms and Xmx settings really do?

8,820 views
Skip to first unread message

Mike Hopper

unread,
Oct 19, 2010, 5:46:38 PM10/19/10
to The Java Posse
I've been doing Java development for many years but sometimes
something surprises me. A coworker was explaining to me that many JVMs
allocate all of the memory specified by the -Xmx parameter at
application startup time. He said that this was an optimization
feature and that the JVM needs to ensure that it gets a contiguous
address space for its heap at startup. Some google searches confirmed
that this is the case for the IBM JVM.

One reason this discussion came up is because we could not start a web
app with -Xmx=1gb (even though 2gb were free) because (according to
his explanation) the OS could not find 1gb of contiguous memory. He
resolved the issue by rebooting the machine (thus defragging the
physical memory).

Anyone here familiar with this. It seemed strange to me because (a)
why have both Xms and Xmx settings if the JVM is just going to grab
all the memory it will ever need at startup? (b) Eclipse, which is a
Java app, seems to grow and shrink its memory footprint throughout the
day (at least on Windows). Perhaps different JVMs have different
strategies for grabbing memory from OS.

Any insight would be appreciated.

Mike

ags

unread,
Oct 20, 2010, 4:43:32 PM10/20/10
to java...@googlegroups.com
Couldn't start meaning an out of memory exception or what?

Stuart McCulloch

unread,
Oct 20, 2010, 6:00:13 PM10/20/10
to java...@googlegroups.com
IIRC the JVM uses mmap to check the OS has enough contiguous address space for -Xmx,
but it uses the MAP_NORESERVE flag which means the OS won't actually allocate system
resources to the process until pages are actually used (which is where -Xms comes in)

[ I haven't delved into JVM code for a while, so this might not be accurate or up-to-date!
  Memory allocation code also varies from OS to OS, but the general idea is the same ]
 
Any insight would be appreciated.

Mike

--
You received this message because you are subscribed to the Google Groups "The Java Posse" group.
To post to this group, send email to java...@googlegroups.com.
To unsubscribe from this group, send email to javaposse+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/javaposse?hl=en.

--
Cheers, Stuart

Reinier Zwitserloot

unread,
Oct 21, 2010, 3:06:50 AM10/21/10
to The Java Posse
Without -Xmx, you basically get -Xmx64m, and the VM will NOT attempt
to allocate more than that. Instead, it'll first fire up the collector
and when that fails, it'll start throwing OOMEs. Though, if you're
getting near the limit, first the VM will slow down to a crawl (due to
repeated calls to the garbage collector, as the practical memory space
is reduced to an ever smaller amount of memory, forcing lots of GC
cycles), and then it'll start throwing OOMEs. (I'm not sure if 64m is
still the standard if you don't add an -Xmx, though).

-Xmx will increase the point at which the VM stops allocating memory
and instead uses GC and OOME.

-Xms, well, it _sounds_ like this simply forces actually allocing all
that memory right away instead of doing that on the fly, but this is
where I get a little fuzzy. Normally -Xmx will get the job done.

Mike Hopper

unread,
Oct 21, 2010, 12:04:48 PM10/21/10
to The Java Posse
I finally found some good articles regarding this issue. It seems like
the key is understanding the difference between reserved memory and
committed memory. Many JVMs require that the amount of memory
specified by -Xmx be available as contiguous reserved memory, which is
usually reserved in the virtual memory / swap space. But if there is
not enough swap space (I've seen some environments at work where we
have configured 6GB physical but only 2GB swap), then the OS may try
to reserve it all as physical memory. If both fails, the JVM cannot
load. (I'm a bit fuzzy on the last part about reserving it in physical
memory but I think this is how it works).

So to summarize, if we set JAVA_OPTS=-Xms256m -Xmx1g then we are
requesting at startup time to have 256mb of committed memory (which
must be available as physical memory but may get paged out later) and
1gb of (contiguous) reserved virtual memory that can be incrementally
converted to committed memory as needed.

Also adding some confusion is that many tools don't report the
reserved memory, but only the committed physical and committed paged-
out memory.

Below is a link that helped me with this. It is specific to the
Windows OS but I think most of the concepts apply to other OS's.

http://www.ibm.com/developerworks/library/j-memusage/

A related question is this: does it help performance to set -Xms value
equal to -Xmx value? Several developers at my work do this saying that
it increases performance, but I'm a bit skeptical that it makes much
of a difference. It is certainly a "selfish" way to startup a Java app
("give me all this committed memory on startup!") but if you know your
application will need it all in a hurry (large dataset processing)
then I guess it makes some sense.

Regards,

Mike

Miroslav Pokorny

unread,
Oct 21, 2010, 5:22:33 PM10/21/10
to java...@googlegroups.com
On Wed, Oct 20, 2010 at 8:46 AM, Mike Hopper <drm...@gmail.com> wrote:
I've been doing Java development for many years but sometimes
something surprises me. A coworker was explaining to me that many JVMs
allocate all of the memory specified by the -Xmx parameter at
application startup time. He said that this was an optimization
feature and that the JVM needs to ensure that it gets a contiguous
address space for its heap at startup. Some google searches confirmed
that this is the case for the IBM JVM.

Why did you include contiguous in your statement. Most (all(??) modern processors hve an MMU and use a table to hold pages thus mapping pages into one long contiguous chunk is not a problem providing it can find enough pages.

Les Stroud

unread,
Oct 21, 2010, 6:08:10 PM10/21/10
to The Java Posse
In principle, you get an improvement in performance be specing the -
Xms because that memory is reserved and committed. So, if the machine
is able to reserve that amount of contiguous space in RAM and the OS
is not having to page in order to meet that requirement, then, when
your application needs the memory, the OS does not need to page in
order to provide it. That is the savings.

Many OSes optimize this paging. Those specific optimizations make
this much hairier. Solaris, for instance, does a very nice job of
reducing paging time. You can see this with Dtrace. I don't remember
the specifics, but they had tuned that behavior very, very well.
Linux is not quite as efficient, and windows (at least server 03 and
xp...don't know about server 08) is not as efficient when paging
memory to Java applications. Mac does pretty good too (dtrace on
their is really helpful), but who uses that for servers? :P

So, depending on your platform and configuration that performance
tweak can help. More often than not, there are plenty of other things
that can be done to improve performance before you get to the level
that reserving memory will make a drastic difference. If you want to
see for yourself, get a machine of vm running solaris (or a mac) and
run your app with the lower Xms setting. You should see extra system
calls for your operations. In fact, you may be able to detect this
using vmstat if you have a quite box.

LES

Steven Herod

unread,
Oct 21, 2010, 10:42:46 PM10/21/10
to The Java Posse

" but this is where I get a little fuzzy. "

Fuzzy? You? Who are you and what have you done with Reinier!

:)


Kirk

unread,
Oct 22, 2010, 6:13:02 AM10/22/10
to java...@googlegroups.com
If you specify Xms=Xmx you will in effect hinder the adaptive run time memory management features of the JVM. I wouldn't do this as a matter of course. I'd only do it *if* it had a positive measurable effect on performance.

In general, the JVM should *never* page. You don't want to page during a STW GC pause. To avoid it, look into using large pages. All Linux/Unix distro's support the feature. You'll get better performance due to better object locality than you will be messing about with reserved vs committed memory.

Regards,
Kirk

Reply all
Reply to author
Forward
0 new messages