简体   繁体   English

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

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

I have two linux machines (both are VMs), one having 12GB memory and other having 8GB memory. 我有两台Linux机器(都是VM),一台有12GB内存,另一台有8GB内存。

I tried to start the same java program on both machines, with maximum max heap size possible (using -Xmx flag). 我尝试在两台机器上启动相同的java程序,最大可能的最大堆大小(使用-Xmx标志)。 Following are the results I got. 以下是我得到的结果。

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

If I specify a max heap size beyond above limits, I get below error. 如果我指定超出上限的最大堆大小,我会得到以下错误。

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

I checked the free memory in two systems (using free command), and I got following. 我检查了两个系统中的空闲内存(使用free命令),我得到了以下内容。

  • 12GB machine: approximately 3GB free. 12GB机器:大约3GB免费。
  • 8GB machine: approximately 4GB free. 8GB机器:大约4GB免费。

My question is, what determines the maximum max heap size a java program can be started with, which would not result in above mentioned error? 我的问题是,什么决定了java程序可以启动的最大最大堆大小,这不会导致上述错误? (System had sufficient memory to allocate 1073741824 bytes of memory when the program gave above error) (当程序给出上述错误时,系统有足够的内存来分配1073741824字节的内存)

I have found interesting comments from JDK bug ( The bug in JDK 9 version and not in 8. It says bug was fixed in 8.x version but does not tell minor build number. 我从JDK bug中找到了有趣的评论(JDK 9版本中的错误,而不是8中的错误。它说错误在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. 如果虚拟内存受限于“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

Comments: 评论:

The problem seems to be that we must specify MALLOC_ARENA_MAX. 问题似乎是我们必须指定MALLOC_ARENA_MAX。

If I set the environment variable MALLOC_ARENA_MAX=4, then the jvm can start without any extra arguments. 如果我设置环境变量MALLOC_ARENA_MAX = 4,那么jvm可以在没有任何额外参数的情况下启动。

I guess that this is not something that can be fixed from the jvm. 我想这不是可以从jvm修复的东西。 If so we can close this bug. 如果是这样,我们可以关闭这个bug。

When using "UseConcMarkSweepGC" then the command line above does not work. 使用“UseConcMarkSweepGC”时,上面的命令行不起作用。 I have tried to add MaxMetaspaceSize=128m, but it does not help. 我试图添加MaxMetaspaceSize = 128m,但它没有帮助。 I am sure there are an argument that makes it work, but I have not found one. 我确信有一个论点可以让它发挥作用,但我还没找到。 Configuring the GC with limited virtual memory is not very user friendly. 使用有限的虚拟内存配置GC不是非常用户友好。

Change parameters to as per your requirement and try this one. 根据您的要求更改参数并尝试这一个。

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

I did some experiments with the clues given by ravindra and found that the maximum max heap size has a direct relationship with the total virtual memory available in the system. 我用ravindra给出的线索进行了一些实验,发现最大最大堆大小与系统中可用的总虚拟内存有直接关系。

Total virtual memory in the system can be found (in KB) with: 可以找到系统中的总虚拟内存(以KB为单位):

ulimit-v

Total virtual memory can be altered with: 可以通过以下方式更改总虚拟内存:

ulimit -v <new amount in KB>

The maximum max heap size possible was approximately 2GB less than the virtual memory. 可能的最大最大堆大小比虚拟内存少大约2GB。 If you specify unlimited virtual memory using ulimit -v unlimited , You can specify any large value for the max heap size. 如果使用ulimit -v unlimited指定无限制虚拟内存,则可以为最大堆大小指定任何大值。

The memory you have available is the combination of free RAM plus swap space. 您可用的内存是空闲RAM和交换空间的组合。 It also depends on whether the system has overcommit enabled — if so, the kernel will allow programs to allocate more memory than is actually available (within reasonable limits), since programs often allocate more than they're really going to use. 它还取决于系统是否启用了overcommit - 如果是这样,内核将允许程序分配比实际可用内存更多的内存(在合理的限制内),因为程序通常分配的内容超过它们实际使用的内容。

Note that overcommit is enabled by default. 请注意,默认情况下启用overcommit。 To disable it, write 2 into /proc/sys/vm/overcommit_memory . 要禁用它,请将2写入/proc/sys/vm/overcommit_memory (Strangely, a value of 0 does not mean "no overcommit".) But it's a good idea to read the overcommit documentation first. (奇怪的是,值为0并不意味着“没有过度使用”。)但是首先阅读过度使用的文档是个好主意。

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

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