位JVM限于300GB的内存?

我正尝试在集群计算环境(运行CentOS 6.2版Final的IBM LSF)上运行Java应用程序,它可以为我提供高达1TB的RAM空间。

我可以创建一个具有高达300GB最大内存(Xmx)的JVM,尽管我需要更多的内容(如果需要,我可以提供详细信息)。

但是,使用Xmx选项创建具有超过300GB最大内存的JVM似乎是不可能的。 更具体地说,我得到了经典的错误信息:

VM初始化期间发生错误。

无法为对象堆预留足够的空间。

我的(64位)JVM的细节如下:

OpenJDK运行时环境(IcedTea6 1.10.6)(rhel-1.43.1.10.6.el6_2-x86_64)

OpenJDK 64位服务器虚拟机(构建20.0-b11,混合模式)

我也尝试过使用Java 7 64位JVM,但我遇到了完全相同的问题。

此外,我尝试创建一个JVM来运行HelloWorld.jar,但如果您要求超过-Xmx300G,JVM创建仍然会失败,所以我认为它与特定应用程序没有任何关系。


有没有人有任何想法,为什么我不能创建超过300G的最大内存的JVM?

任何人都可以请建议一个解决方案/解决方法?


我可以想到几个可能的解释:

  • 您系统上的其他应用程序使用的内存太多,目前没有300Gb可用。

  • 每个进程内存大小可能存在资源限制。 你可以使用ulimit来检查。 (请注意,根据此错误,如果每进程资源限制停止JVM分配堆区域,则将收到错误消息。)

  • 这也可能是一个“过度提交”的问题; 例如,如果您的应用程序运行在虚拟环境中,并且整个系统无法满足需求,因为其他虚拟环境存在太多竞争。


  • 建议的其他一些想法是(IMO)不太可能的:

  • 切换JRE不会有什么不同。 我从来没有听说过或看过特定64位JVM中的任意内存限制。

  • 这不可能是因为没有足够的连续内存。 当然不需要连续的物理内存。 唯一的可能性可能是交换设备上的连续空间,但我不记得这是典型Linux操作系统的问题。


  • 任何人都可以请建议一个解决方案/解决方法?

  • 检查ulimit

  • 编写一个小型的C程序,试图malloc大量的内存,看看有多少可以分配之前,它失败。

  • 请求系统(或管理程序)管理员寻求帮助。


  • (已编辑,请参阅交换空间的添加部分)

    SHMMAX和SHMALL

    由于您使用的是CentOS,因此您可能会遇到类似于SHMMAXSHMALL内核设置的问题,如配置Oracle数据库所述。 在同样的链接下,用于获取和设置正确的SHMALL设置的示例计算。

    连续的记忆

    某些用户已经报告说没有足够的连续内存可用,其他人则表示这是不相关的。

    我不确定CentOS上的JVM是否需要连续的内存块。 根据SAS的说法,碎片内存可能会阻止您的JVM使用大型最大Xmx启动或启动Xms内存设置,但互联网上的其他声明表示无关紧要。 我试图在我的48GB Windows工作站上证明或解决这种索赔,但设法以40GB的初始和最大设置启动JVM。 我确信没有可用的连续块,但是不同操作系统上的JVM可能会有不同的表现,因为每个操作系统的内存管理可能不同(即,Windows通常隐藏单个进程的物理地址)。

    寻找最大的连续内存块

    使用/proc/meminfo查找可用的最大连续内存块,请参阅VmAllocChunk下的值。 以下是对所有值的指导和解释。 如果您在那里看到的值小于300GB,请尝试一个VmAllocChunk值的值。

    但是,通常这个数字比物理可用内存高(因为它是可用的虚拟内存值),它可能会给你一个误报。 这是您可以保留的价值,但一旦您开始使用它,可能需要交换。 因此,您应该检查MemFreeInactive值。 相反,您也可以查看整个列表并查看哪些值不超过300GB。

    其他调优选项可以检查64位JVM

    我不确定你为什么在300GB时遇到内存限制问题。 有一刻我想你可能已经达到了最多的页数。 默认为4kB,300GB为78,643,200页。 看起来不像一些知名的神奇数字。 例如,如果2^24是最大值,那么16,777,216页或64GB应该是您理论上可分配的最大值。

    但是,为了争辩的目的,假设您需要更大的页面(事实证明,对于大型内存Java应用程序的性能更好),您应该参考JBoss上的这个手册页,它解释了如何使用-XX:+UseLargePages并设置kernel.shmmax (它再次), vm.nr_hugepagesvm.huge_tlb_shm_group (不确定后者是否需要)。

    强调你的系统

    其他人也建议这一点。 要发现问题出在JVM而不是OS上,你应该对它进行压力测试。 一个你可以使用的工具是Stresslinux。 在本教程中,您可以找到一些可以使用的选项。 您特别感兴趣的是以下命令:

    stress --vm 2 --vm-bytes 300G --timeout 30s --verbose
    

    如果该命令失败或锁定系统,则知道操作系统正在限制使用该内存量。 如果成功,我们应该尝试调整JVM,使其可以使用可用内存。

    编辑Apr6:检查交换空间

    内存容量非常大的系统很少使用或不使用交换空间,这种情况并不少见。 对于许多应用程序来说,这可能不成问题,但JVM要求交换可用交换空间大于请求的内存大小。 根据这个错误报告,JVM会尝试增加交换空间本身,然而,正如本SO线程中的一些答案所建议的那样,JVM可能并不总能这样做。

    因此:使用cat /proc/swaps # free检查当前可用的交换空间,如果它小于300GB,请按照CentOS联机帮助页上的说明增加系统的交换空间。

    注1:我们可以从bugreport#4719001中扣除可用交换空间的连续块不是必需的。 但是,如果您不确定,请删除所有交换空间并重新创建它,这应删除任何碎片。

    注2:我看过几篇文章,其中包括0MB交换空间,并且能够运行JVM。 这可能是由于JVM本身增加了交换空间。 仍然不会尝试手动增加交换空间,以确定它是否解决了您的问题。

    过早的结论

    我意识到,以上的不是对你的问题的一个开箱即用的答案。 我希望它给你一些指示,尽管你可以尝试让你的JVM工作。 如果问题的结果是您当前使用的JVM的限制,您可能还会尝试使用其他JVM,但从目前为止所读取的内容来看,对64位JVM不应施加任何限制。

    您在JVM初始化时遇到错误会让我相信问题不在于JVM,而是操作系统无法遵守300GB内存的预留。

    我自己的测试表明JVM可以访问所有的虚拟内存,并且不关心可用的物理内存量。 如果虚拟内存低于物理内存,那将会很奇怪,但VmAllocChunk设置应该会给你提供一个方向提示(它通常要大得多)。


    如果您看看Java HotSpot VM的FAQ部分,它提到在64位VM上只有64个地址位可以使用,因此最大的Java堆大小取决于物理内存和交换空间的大小目前在系统上。

    如果你从理论上计算,那么你可以拥有18446744073709551616 MB的记忆,但是它有上述限制。

    您必须使用-Xmx命令为JVM定义最大堆大小。默认情况下,Java在64位JVM上使用64 + 30%= 83.2MB。

    我在我的机器上尝试了下面的命令,它看起来工作正常。

    java -Xmx500g com.test.TestClass
    

    我也尝试在TB中定义最大堆,但它不起作用。

    链接地址: http://www.djcxy.com/p/82909.html

    上一篇: bit JVM limited to 300GB of memory?

    下一篇: Java error centos 6