Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

32-bit JVM on 64-bit Windows crashes on launch with -Xmx1300m and plenty of free memory

Tags:

java

jvm

I'm struggling with Java heap space settings. The default Java on Windows is the 32-bit client regardless of OS version (that's what Oracle recommends to all users). It appears to set max heap size to 256 MB by default, and that is too little for me.

I use a custom launcher to start the application. I would like it to use more memory on computers with plenty RAM, and default to -Xmx512m on those with less RAM. As far as I'm aware, the only way is the static -Xmx setting (that has to be set on launch).

I have a user who has 8 GB RAM, 64-bit Windows and 32-bit Java 7. Maximum memory visible to the JVM is 4G (as returned by querying OperatingSystemMXBean). I understand why, no issue.

For some reason my application is unable to start for this user with -Xmx1300m, even though he has 2.3G free memory. He closed some applications (having 5G free memory), and still it would not launch. The error reported to me was:

error occured during init of vm
could not reserve enough space for object heap

What's going on? Could it be that the 32-bit JVM is only able to address the "first" 4G of memory and has to have a 1300M block available within those first 4 gigabytes?

How can I solve this problem, except for asking everyone to install 64-bit Java (what is unlikely to be acceptable)?

EDIT: In case it matters, it is a fat Swing client, not an applet.

like image 203
Konrad Garus Avatar asked Jun 24 '13 16:06

Konrad Garus


People also ask

What is the maximum heap size of 32-bit and 64 bit JVM?

Max Heap Size. The maximum theoretical heap limit for the 32-bit and 64-bit JVM is easy to determine by looking at the available memory space, 2^32 (4 GB) for 32-bit JVM and 2^64 (16 Exabytes) for 64-bit JVM. In practice, due to various constraints, the limit can be much lower and varies given the operating system.

What are the reasons of JVM crashes?

A Java application might stop running for several reasons. The most common reason is that the application finished running or was halted normally. Other reasons might be Java application errors, exceptions that cannot be handled, and irrecoverable Java errors like OutOfMemoryError .

What is the max heap size for 32-bit JVM?

The maximum theoretical heap limit for the 32-bit JVM is 4G. Due to various additional constraints such as available swap, kernel address space usage, memory fragmentation, and VM overhead, in practice the limit can be much lower. On most modern 32-bit Windows systems the maximum heap size will range from 1.4G to 1.6G.

How do I fix there is insufficient memory for the Java Runtime Environment to continue?

# There is insufficient memory for the Java Runtime Environment to continue. This is due to a known Java bug when process-limiting the virtual memory via ulimit (https://bugs.openjdk.java.net/browse/JDK-8071445). To resolve this, please set the max heap limits to a reasonable value.


2 Answers

It is not a question of memory but a question of address space.

On those 4 GB (2^32) theoretically addressable by a 32bit process, one must take into account the fact that the OS kernel needs a part of that address space (which obviously the process cannot touch).

And when you use Java, the address space of the java process itself is split further, between the heap, the permgen, native resources, the JVM itself etc.

You are using a 64bit OS. Run a 64bit JVM. Your bytecode (ie, all your jars) will run all the same. There is just no reason to be using a 32bit JVM!

like image 163
fge Avatar answered Sep 19 '22 02:09

fge


Why won't it work?

As others have mentioned, this particular user's computer most likely does not have a large enough contiguous block of free memory for the JVM in a 32-bit address space. The maximum 32-bit heap space is system-dependent (note that both the OS and the exact JVM version make a difference) but is usually around 1100-1600 MB on Windows. For example, on my 64-bit Windows 7 system, these are my maximum -Xmx sizes for the specific 32-bit JVM versions I have installed:

  • Java 7: between 1100m and 1200m
  • Java 6: between 1400m and 1500m
  • Java 5: between 1500m and 1600m

The remaining memory allocated to the process is used by the OS (or emulator, in the case of a 32-bit process on a 64-bit host), the JVM itself, and other structures used by the JVM.

Recommended solution: bundle a 64-bit JVM with your application

If you cannot get the client to install a 64-bit JVM, bundle one with your application. The 64-bit address space will have a contiguous block of memory larger than 1300 MB free, even if there is not necessarily a large enough contiguous block of physical memory available.

If your software is a standalone application, it's a piece of cake to bundle the JVM. If the launcher is an applet, you might have to have your applet check for the 64-bit JVM in a known location (and download it if necessary) before launching your application.

Don't forget about dependencies

If your application uses 32-bit native libraries, make sure you can also get 64-bit versions of those native libraries.

What if you can't bundle a JVM or have 32-bit native dependencies?

There's really no reason why you shouldn't be able to bundle a JVM with your application, but you might have some 32-bit native dependencies that haven't been ported to 64-bit--in which case, it won't matter whether you bundle a JVM because you're still stuck with 32-bit. In that case, you can make your launcher perform a binary search to determine the maximum heap size by repeatedly executing java -Xmx####m -version and parsing the output (where #### is the Xmx value, of course). Once you've found the maximum Xmx, you can launch your program with that value. (Note: a slightly safer option would be to simply try to run your program and check for the heap space error, decreasing Xmx after each failed attempt to launch your program.)

You'll need to use a smaller Xmx value if you get an error message like one of the following:

Java 7:

Error occurred during initialization of VM
Could not reserve enough space for object heap
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.

Java 6:

Error occurred during initialization of VM
Could not reserve enough space for object heap
Could not create the Java virtual machine.

Java 5:

Error occurred during initialization of VM
Could not reserve enough space for object heap
Could not create the Java virtual machine.

But if you get something like the following, you know you've either found the maximum or you can try a larger Xmx value:

Java(TM) SE Runtime Environment (build 1.7.0_21-b11)
Java HotSpot(TM) Client VM (build 23.21-b01, mixed mode)
like image 37
rob Avatar answered Sep 23 '22 02:09

rob