繁体   English   中英

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

[英]Java: what determines the maximum max heap size possible in a linux machine

我有两台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字节的内存)

我从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

评论:

问题似乎是我们必须指定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

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

可以找到系统中的总虚拟内存(以KB为单位):

ulimit-v

可以通过以下方式更改总虚拟内存:

ulimit -v <new amount in KB>

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM