我有两台电脑在Mac OS X El Capitan和Ubuntu 16.04 LTS上运行。两者都安装了Java SDK 1.8.0_101。
当我尝试使用比可用内存更多的内存在Ubuntu上启动游戏服务器时,我得到以下输出:
$ 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:
#
在Mac OS上我没有收到此错误:
$ java -Xms200G -Xmx200G -jar craftbukkit.jar nogui
Loading libraries, please wait...
两台计算机都有8GB内存。我也试过用另一台Apple电脑 - 同样的问题。
这是java mac版的错误吗?
(有没有办法强制限制内存使用量,例如1GB?-Xmx1G不会工作,我也找不到另一个原因。谷歌也没有这样做)
谢谢!
抱歉我的英语不好......
答案 0 :(得分:1)
操作系统的工作方式不同。 Linux有一个“固定”的概念。 swap - 这是基于物理RAM +添加到系统的各种swapfiles / swap分区。这被认为是可以提交的最大内存限制。
OSX并不认为交换是固定的。随着越来越多的内存在操作系统上提交,它将继续添加交换文件(您可以在/var/vm
中看到正在添加的文件)。
因此,您可以向OSX请求比可用内存更多的内存,它可以有效地回复“确定”,而在Linux下它将会“没有”。
上限仍然由java强制执行 - 一旦堆超过指定的大小,它将返回java.lang.OutOfMemoryError: Java heap space
异常,因此,如果您要指定-Xmx1G
,那么它应该由JRE强制执行。
您可以通过简单的测试程序看到差异:
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());
}
}
};
如果此程序与-Xmx100M
一起运行,它会在〜730次迭代后以Java heap space
消息消失,当使用-Xmx1G
运行时,它会在~7300之后以Java heap space
消息消失迭代,显示java虚拟机强制执行限制。