RFR (S): 7112912:Message "Error occurred during initialization of VM" on boxes with lots of RAM

Thomas Schatzl thomas.schatzl at oracle.com
Thu Mar 14 13:11:43 PDT 2013


On Wed, 2013-03-13 at 12:15 -0700, Tao Mao wrote:
> BTW, upon completion of this CR, please also investigate a CR with
> similar problems (most likely, close as a duplicate) .
> https://jbs.oracle.com/bugs/browse/JDK-6374896

It is most certainly a duplicate.

> On 3/13/13 6:17 AM, Thomas Schatzl wrote: 
> > Hi all,
> > 
> >   please review the following change which improves ergonomic heap
> > sizing. Automatic heap sizing now takes available virtual memory into
> > account.
> > 
> > The problem occurred when the user reduced the available virtual memory
> > via e.g. ulimit. As ergonomics did not take virtual memory into account,
> > using available physical memory only, the vm typically crashed at
> > startup.
> > 
> > This patch does not avoid all crashes due to out of virtual memory,
> > because only heap sizing now takes available virtual memory into account
> > now. Some GCs, and also other parts of the VM, try to reserve hundreds
> > of MB at startup.
> I don't quite understand what you mean here. Does it indicate that the
> default value (i.e. 2) chosen for MaxVirMemFraction is a bit large?
> (when it has the effect of limiting the head size, the virtual memory
> would be small already.) 

No, the problem is that especially at smaller limits (~1-2G) other
memory consumers (i.e. parts that reserve memory upfront) in the vm will
take up the majority of the virtual memory space, exiting the VM.

This not only includes GCs, but also other parts of the VM. As this
patch does not try to limit the memory us of these other consumers the
VM will still exit with out of memory at quite high ulimits, at least
with the 64 bit VM.

The related defaults for the 32 bit VM are much more economical in that

> > The main change is in Arguments::allocatable_physical_memory() (which
> > has been moved from the os class) where if an additional virtual memory
> > limit has been imposed on the java process, the given heap size is
> > bounded by a fraction of that limit.
> It kind of violates parallelism here, for
> Arguments::allocatable_physical_memory() and os::physical_memory() are
> now defined in different classes while they should have the same level
> of abstraction. Seems better to keep allocatable_physical_memory()
> back in os due to its closeness to os.

I think that they serve a different purpose, and are at a different
level of abstraction.

Os::physical_memory() like the new os::has_allocatable_physical_memory
are basically functions that query the OS for information.
Arguments::allocatable_physical_memory uses this information among
other, applying a heuristic to get the "best" heap size in the current

It is quite simple quite now, but an easy extension could be to ask the
GCs how much memory they'd try to allocate given the current conditions.

I believe the os class is mostly a thin layer above OS functionality, so
this does not fit.

I renamed Arguments::allocatable_physical_memory() to
"limit_by_allocatable_memory(julong)" too to decrease the confusion.

Did that answer your question?

> > That fraction is determined by a new global called MaxVirtMemFraction
> > (default value: 2).
> follow the style
> 1946   product(uintx, MaxRAMFraction, 4,                                         \
> 1947           "Maximum fraction (1/n) of real memory used for maximum heap "    \
> 1948           "size")                                                           \
> would be reasonable to phrase the definition similarly, say,
> 1961   product(uintx, MaxVirtMemFraction, 2,                                     \
> 1962           "Maximum fraction (1/n) of virtual memory used for maximum heap size")            \
> 1963                                                                             \
> > 


> > Some discussion points:
> >   - maybe make MaxVirtMemFraction at least notproduct. It does not seem
> > to make much sense to expose that global to the end user, does it? If
> > the user is able to change MaxVirtMemFraction, he/she may as well set an
> > appropriate maximum heap size with the same effect.
> Makes sense.


> > Webrev:
> > http://cr.openjdk.java.net/~tschatzl/7112912/webrev/
> (1) you may want to rephrase the comment or delete it
> 2607       // Make sure that if we have a lot of memory we cap the 32 bit
> 2608       // process space.  The 64bit VM version of this function is a nop.
> 2609       initHeapSize = allocatable_physical_memory(initHeapSize);


> (2) I also prefer a pointer argument here. It's more readable to
> recognize its intention of usage.
> 187   static bool has_allocatable_memory_limit(julong& limit);


> > 
> > CR:
> > http://bugs.sun.com/view_bug.do?bug_id=7112912
> > 
> > JIRA:
> > https://jbs.oracle.com/bugs/browse/JDK-7112912
> > 
> > Testing:
> > jprt, local testing with different ulimit values
> Did you test out all(or, most) platform combinations
> (solaris/bsd/linux/windows + 32/64 bit) to verify the current code can
> get the right size of virtual memory?
> > 

Tested: Linux 32/64 bit, OSX 64 bit, Solaris 32/64 bit, and Windows
32/64 bit (on 64 bit W2k8 server).

On Unixes getrlimit is a basic function, so no problems here, and always
returns the ulimit value (or "unlimited" if not set). For Windows, the
used function is XP+ according to MSDN.
The function to retrieve the total virtual memory is also already in use
by other os class methods without any special guards.

Manually is the better word. :)

I will prepare a new webrev.


More information about the hotspot-gc-dev mailing list