Java:什么决定了linux机器中可能的最大最大堆大小

Lah*_*ima 4 java linux

我有两台Linux机器(都是VM),一台有12GB内存,另一台有8GB内存.

我尝试在两台机器上启动相同的java程序,最大可能的最大堆大小(使用-Xmx标志).以下是我得到的结果.

  • 12GB机器:9460MB
  • 8GB机器:4790MB

如果我指定超出上限的最大堆大小,我会得到以下错误.

Error occurred during initialization of VM
Could not allocate metaspace: 1073741824 bytes
Run Code Online (Sandbox Code Playgroud)

我检查了两个系统中的空闲内存(使用free命令),我得到了以下内容.

  • 12GB机器:大约3GB免费.
  • 8GB机器:大约4GB免费.

我的问题是,什么决定了java程序可以启动的最大最大堆大小,这不会导致上述错误?(1073741824当程序给出上述错误时,系统有足够的内存来分配内存字节)

Rav*_*abu 7

我发现了JDK bug的有趣评论(JDK 9版本中的错误而不是8中的错误.它说错误是在8.x版本中修复但不告诉次要版本号.

如果虚拟内存受限于"ulimit -v",并且服务器有大量RAM,那么如果没有额外的命令行参数,则JVM无法启动.

// After "ulimit -v" The jvm does not start with default command line. 
$ ulimit -S -v 4194304
$ java -version
Error occurred during initialization of VM
Could not allocate metaspace: 1073741824 bytes
Run Code Online (Sandbox Code Playgroud)

评论:

问题似乎是我们必须指定MALLOC_ARENA_MAX.

如果我设置环境变量MALLOC_ARENA_MAX = 4,那么jvm可以在没有任何额外参数的情况下启动.

我想这不是可以从jvm修复的东西.如果是这样,我们可以关闭这个bug.

使用"UseConcMarkSweepGC"时,上面的命令行不起作用.我试图添加MaxMetaspaceSize = 128m,但它没有帮助.我确信有一个论点可以让它发挥作用,但我还没找到.使用有限的虚拟内存配置GC不是非常用户友好.

根据您的要求更改参数并尝试使用此参数.

ulimit -S -v 4194304 
java -XX:MaxHeapSize=512m -XX:InitialHeapSize=512m -XX:CompressedClassSpaceSize=64m -XX:MaxMetaspaceSize=128m -XX:+UseConcMarkSweepGC -version
Run Code Online (Sandbox Code Playgroud)