user2850375
user2850375

Reputation: 79

java on osx - xmx ignored?

i've got two computers running on Mac OS X El Capitan and Ubuntu 16.04 LTS. On both is Java SDK 1.8.0_101 installed.

When I try to start an game server on Ubuntu with more memory than available, I get the following output:

$ java -Xms200G -Xmx200G -jar craftbukkit.jar nogui
Java HotSpot(TM) 64-Bit Server VM warning: INFO: os::commit_memory(0x00007f9b6e580000, 71582613504, 0) failed; error='Cannot allocate memory' (errno=12)
#
# There is insufficient memory for the Java Runtime Environment to continue.
# Native memory allocation (mmap) failed to map 71582613504 bytes for committing reserved memory.
# An error report file with more information is saved as:
# 

On Mac OS I don't get this error:

$ java -Xms200G -Xmx200G -jar craftbukkit.jar nogui
Loading libraries, please wait...

Both computers have 8GB of memory. I also tried with an other Apple computer - same problem.

Is that a bug of java mac version?

(Is there a way to force limit the memory usage e.g. to 1GB? -Xmx1G won't work and I wasn't able to find another reason. Not here neither on google)

Thank you!

Sorry for my bad english...

Upvotes: 1

Views: 846

Answers (1)

Anya Shenanigans
Anya Shenanigans

Reputation: 94829

It's a difference in how the operating systems work. Linux has a concept of a 'fixed' swap - this is based on physical RAM + the various swapfiles/swap partitions added to the system. This is considered the maximum limit of memory that can be committed.

OSX doesn't consider swap as fixed. It will continue to add swapfiles as more and more memory is committed on the operating system (you can see the files being added in /var/vm).

As a result, you can ask OSX for significantly more memory than is available and it will effectively reply with 'ok', while under linux it will go 'no'.

The upper-bound limit is still enforced by java - once the heap goes above the size specified it will return a java.lang.OutOfMemoryError: Java heap space exception, so if you're specifying a -Xmx1G then it should be enforced by the JRE.

You can see the difference with a simple test program:

import java.util.Vector;

public class memtest {

    public static void main(String args[]) throws Exception {
        Vector<byte[]> v = new Vector<byte[]>();
        while (true) {
            v.add(new byte[128 * 1024]);
            System.out.println(v.size());
        }

    }
};

If this program is run with -Xmx100M it dies with a Java heap space message after ~730 iterations, when run with -Xmx1G it dies with a Java heap space message after ~7300 iterations, showing that the limit is being enforced by the java virtual machine.

Upvotes: 1

Related Questions