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

2024-09-27 09:25:33 发布

您现在位置:Python中文网/ 问答频道 /正文

我有两台linux机器(都是vm),一台内存为12GB,另一台内存为8GB。

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

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

如果指定的最大堆大小超出了上述限制,则会低于错误值。

Error occurred during initialization of VM
Could not allocate metaspace: 1073741824 bytes

我检查了两个系统中的可用内存(使用free命令),得到了以下结果。

  • 12GB机器:大约3GB可用空间。
  • 8GB机器:大约4GB空闲空间。

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


Tags: 内存程序机器标志linux系统错误空间
3条回答

可用内存是可用RAM加交换空间的组合。这还取决于系统是否启用了overcommit如果启用了,内核将允许程序分配比实际可用的内存更多的内存(在合理的限制内),因为程序通常分配的内存比实际使用的内存多。

请注意,默认情况下会启用overcommit。要禁用它,请将2写入/proc/sys/vm/overcommit_memory。(奇怪的是,值0并不意味着“没有overcommit”。)但是最好先阅读overcommit文档。

我发现了来自JDK bug(JDK 9版本中的bug,而不是8版本中的bug)的有趣注释。它说这个错误在8.x版本中已经修复,但是没有告诉小的内部版本号。

If virtual memory has been limited with "ulimit -v", and the server has a lot of RAM, then the JVM can not start without extra command line arguments to the GC.

// 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

评论:

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

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

我想这不是可以从jvm修复的。如果可以的话,我们可以关闭这个漏洞。

使用“UseConcMarkSweepGC”时,上面的命令行不起作用。 我试图添加MaxMetaspaceSize=128m,但没有帮助。 我确信有一个论点能使它起作用,但我还没有找到一个。 用有限的虚拟内存配置GC不太方便用户。

根据需要将参数更改为,然后尝试此操作。

ulimit -S -v 4194304 
java -XX:MaxHeapSize=512m -XX:InitialHeapSize=512m -XX:CompressedClassSpaceSize=64m -XX:MaxMetaspaceSize=128m -XX:+UseConcMarkSweepGC -version

我用ravindra给出的线索做了一些实验,发现最大堆大小与系统中可用的虚拟内存总量有直接关系。

系统中的虚拟内存总量(以KB为单位)可以使用:

ulimit-v

总虚拟内存可以更改为:

ulimit -v <new amount in KB>

最大堆大小可能比虚拟内存小大约2GB。如果使用ulimit -v unlimited指定无限虚拟内存,则可以为最大堆大小指定任何大值。

相关问题 更多 >

    热门问题