我有两台Linux机器(都是VM),一台有12GB内存,另一台有8GB内存.
我尝试在两台机器上启动相同的java程序,最大可能的最大堆大小(使用-Xmx标志).以下是我得到的结果.
如果我指定超出上限的最大堆大小,我会得到以下错误.
Error occurred during initialization of VM
Could not allocate metaspace: 1073741824 bytes
Run Code Online (Sandbox Code Playgroud)
我检查了两个系统中的空闲内存(使用free命令),我得到了以下内容.
我的问题是,什么决定了java程序可以启动的最大最大堆大小,这不会导致上述错误?(1073741824当程序给出上述错误时,系统有足够的内存来分配内存字节)
我发现了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)
| 归档时间: |
|
| 查看次数: |
7390 次 |
| 最近记录: |