Java 为什么64位JVM在到达xmx之前就会抛出内存?

Java 为什么64位JVM在到达xmx之前就会抛出内存?,java,jvm,64-bit,jvm-arguments,Java,Jvm,64 Bit,Jvm Arguments,我正在努力解决java应用程序的大内存需求 为了解决更多的内存问题,我不得不切换到64位JVM,并使用大型xmx。 然而,当xmx超过2GB时,应用程序的内存似乎比预期的要早。 当使用2400M的xmx运行并从-verbosegc查看GC信息时,我得到 [Full GC 2058514K->2058429K(2065024K), 0.6449874 secs] …然后它抛出内存不足异常我希望它在耗尽内存之前将堆增加到2065024K以上。 在一个简单的例子中,我有一个测试程序,它在循环

我正在努力解决java应用程序的大内存需求

为了解决更多的内存问题,我不得不切换到64位JVM,并使用大型xmx。 然而,当xmx超过2GB时,应用程序的内存似乎比预期的要早。 当使用2400M的xmx运行并从
-verbosegc
查看GC信息时,我得到

[Full GC 2058514K->2058429K(2065024K), 0.6449874 secs] 
…然后它抛出内存不足异常我希望它在耗尽内存之前将堆增加到2065024K以上。

在一个简单的例子中,我有一个测试程序,它在循环中分配内存,并从
Runtime.getRuntime().maxMemory()
Runtime.getRuntime().totalMemory()
打印信息,直到它最终耗尽内存

在一系列xmx值上运行此命令,似乎
Runtime.getRuntime().maxMemory()
报告的内存比xmx少约10%,并且总内存不会超过
Runtime.getRuntime().maxMemory()
的90%

我正在使用以下64位jvm:

java version "1.6.0_26" Java(TM) SE Runtime Environment (build 1.6.0_26-b03) Java HotSpot(TM) 64-Bit Server VM (build 20.1-b02, mixed mode) 我使用这个批处理文件在多个xmx设置上运行它。它包括对32位JVM的引用,我想与32位JVM进行比较——显然,只要xmx大于1500M,这个调用就会失败

@echo off
set java64=<location of 64bit JVM>
set java32=<location of 32bit JVM>
set xmxval=64


:start


SET /a xmxval  = %xmxval% + 64

 %java64%  -Xmx%xmxval%m  -XX:+UseCompressedOops -XX:+DisableExplicitGC XmxTester %xmxval%

%java32% -Xms28m -Xmx%xmxval%m   XmxTester %xmxval%

if %xmxval% == 4500 goto end
goto start
:end
pause
@echo关闭
设置java64=
设置java32=
设置xmxval=64
:开始
设置/a xmxval=%xmxval%+64
%java64%-Xmx%xmxval%m-XX:+UseCompressedOops-XX:+DisableExplicitGC-xmxtest%xmxval%
%java32%-Xms28m-Xmx%xmxval%m xmxtest%xmxval%
如果%xmxval%==4500转到结束
开始
:结束
暂停
这会弹出一个csv,当放入excel时,它看起来是这样的(为我这里的糟糕格式道歉)

32位

XMX max mem total mem free mem %of xmx used before out of mem exception 128 127 127 125 2 98.4% 192 191 191 189 1 99.0% 256 254 254 252 2 99.2% 320 318 318 316 1 99.4% 384 381 381 379 2 99.5% 448 445 445 443 1 99.6% 512 508 508 506 2 99.6% 576 572 572 570 1 99.7% 640 635 635 633 2 99.7% 704 699 699 697 1 99.7% 768 762 762 760 2 99.7% 832 826 826 824 1 99.8% 896 889 889 887 2 99.8% 960 953 953 952 0 99.9% 1024 1016 1016 1014 2 99.8% 1088 1080 1080 1079 1 99.9% 1152 1143 1143 1141 2 99.8% 1216 1207 1207 1205 2 99.8% 1280 1270 1270 1268 2 99.8% 1344 1334 1334 1332 2 99.9% 128 122 122 116 6 90.6% 192 187 187 180 6 93.8% 256 238 238 232 6 90.6% 320 285 281 275 6 85.9% 384 365 365 359 6 93.5% 448 409 409 402 6 89.7% 512 455 451 445 6 86.9% 576 512 496 489 7 84.9% 640 595 595 565 30 88.3% 704 659 659 629 30 89.3% 768 683 682 676 6 88.0% 832 740 728 722 6 86.8% 896 797 772 766 6 85.5% 960 853 832 825 6 85.9% 1024 910 867 860 7 84.0% 1088 967 916 909 6 83.5% 1152 1060 1060 1013 47 87.9% 1216 1115 1115 1068 47 87.8% 1280 1143 1143 1137 6 88.8% 1344 1195 1174 1167 7 86.8% 1408 1252 1226 1220 6 86.6% 1472 1309 1265 1259 6 85.5% 1536 1365 1317 1261 56 82.1% 1600 1422 1325 1318 7 82.4% 1664 1479 1392 1386 6 83.3% 1728 1536 1422 1415 7 81.9% 1792 1593 1455 1448 6 80.8% 1856 1650 1579 1573 6 84.8% 1920 1707 1565 1558 7 81.1% 1984 1764 1715 1649 66 83.1% 2048 1821 1773 1708 65 83.4% 2112 1877 1776 1769 7 83.8% 2176 1934 1842 1776 66 81.6% 2240 1991 1899 1833 65 81.8% 2304 2048 1876 1870 6 81.2% 2368 2105 1961 1955 6 82.6% 2432 2162 2006 2000 6 82.2% XMX max mem total mem free mem%在超出mem异常之前使用的XMX 128 127 127 125 2 98.4% 192 191 191 189 1 99.0% 256 254 254 252 2 99.2% 320 318 318 316 1 99.4% 384 381 381 379 2 99.5% 448 445 445 443 1 99.6% 512 508 508 506 2 99.6% 576 572 572 570 1 99.7% 640 635 635 633 2 99.7% 704 699 699 697 1 99.7% 768 762 762 760 2 99.7% 832 826 826 824 1 99.8% 896 889 889 887 2 99.8% 960 953 953 952 0 99.9% 1024 1016 1016 1014 2 99.8% 1088 1080 1080 1079 1 99.9% 1152 1143 1143 1141 2 99.8% 1216 1207 1207 1205 2 99.8% 1280 1270 1270 1268 2 99.8% 1344 1334 1334 1332 2 99.9% 64位

XMX max mem total mem free mem %of xmx used before out of mem exception 128 127 127 125 2 98.4% 192 191 191 189 1 99.0% 256 254 254 252 2 99.2% 320 318 318 316 1 99.4% 384 381 381 379 2 99.5% 448 445 445 443 1 99.6% 512 508 508 506 2 99.6% 576 572 572 570 1 99.7% 640 635 635 633 2 99.7% 704 699 699 697 1 99.7% 768 762 762 760 2 99.7% 832 826 826 824 1 99.8% 896 889 889 887 2 99.8% 960 953 953 952 0 99.9% 1024 1016 1016 1014 2 99.8% 1088 1080 1080 1079 1 99.9% 1152 1143 1143 1141 2 99.8% 1216 1207 1207 1205 2 99.8% 1280 1270 1270 1268 2 99.8% 1344 1334 1334 1332 2 99.9% 128 122 122 116 6 90.6% 192 187 187 180 6 93.8% 256 238 238 232 6 90.6% 320 285 281 275 6 85.9% 384 365 365 359 6 93.5% 448 409 409 402 6 89.7% 512 455 451 445 6 86.9% 576 512 496 489 7 84.9% 640 595 595 565 30 88.3% 704 659 659 629 30 89.3% 768 683 682 676 6 88.0% 832 740 728 722 6 86.8% 896 797 772 766 6 85.5% 960 853 832 825 6 85.9% 1024 910 867 860 7 84.0% 1088 967 916 909 6 83.5% 1152 1060 1060 1013 47 87.9% 1216 1115 1115 1068 47 87.8% 1280 1143 1143 1137 6 88.8% 1344 1195 1174 1167 7 86.8% 1408 1252 1226 1220 6 86.6% 1472 1309 1265 1259 6 85.5% 1536 1365 1317 1261 56 82.1% 1600 1422 1325 1318 7 82.4% 1664 1479 1392 1386 6 83.3% 1728 1536 1422 1415 7 81.9% 1792 1593 1455 1448 6 80.8% 1856 1650 1579 1573 6 84.8% 1920 1707 1565 1558 7 81.1% 1984 1764 1715 1649 66 83.1% 2048 1821 1773 1708 65 83.4% 2112 1877 1776 1769 7 83.8% 2176 1934 1842 1776 66 81.6% 2240 1991 1899 1833 65 81.8% 2304 2048 1876 1870 6 81.2% 2368 2105 1961 1955 6 82.6% 2432 2162 2006 2000 6 82.2% 128 122 122 116 6 90.6% 192 187 187 180 6 93.8% 256 238 238 232 6 90.6% 320 285 281 275 6 85.9% 384 365 365 359 6 93.5% 448 409 409 402 6 89.7% 512 455 451 445 6 86.9% 576 512 496 489 7 84.9% 640 595 595 565 30 88.3% 704 659 659 629 30 89.3% 768 683 682 676 6 88.0% 832 740 728 722 6 86.8% 896 797 772 766 6 85.5% 960 853 832 825 6 85.9% 1024 910 867 860 7 84.0% 1088 967 916 909 6 83.5% 1152 1060 1060 1013 47 87.9% 1216 1115 1115 1068 47 87.8% 1280 1143 1143 1137 6 88.8% 1344 1195 1174 1167 7 86.8% 1408 1252 1226 1220 6 86.6% 1472 1309 1265 1259 6 85.5% 1536 1365 1317 1261 56 82.1% 1600 1422 1325 1318 7 82.4% 1664 1479 1392 1386 6 83.3% 1728 1536 1422 1415 7 81.9% 1792 1593 1455 1448 6 80.8% 1856 1650 1579 1573 6 84.8% 1920 1707 1565 1558 7 81.1% 1984 1764 1715 1649 66 83.1% 2048 1821 1773 1708 65 83.4% 2112 1877 1776 1769 7 83.8% 2176 1934 1842 1776 66 81.6% 2240 1991 1899 1833 65 81.8% 2304 2048 1876 1870 6 81.2% 2368 2105 1961 1955 6 82.6% 2432162 2006 2000 6 82.2%为什么会发生这种情况

基本上,JVM/GC可以使用两种策略来决定何时放弃并抛出OOME

  • 它可以一直运行,直到垃圾收集后内存不足,无法分配下一个对象为止

  • 它可以一直运行,直到JVM花费超过给定百分比的时间运行垃圾收集器

第一种方法的问题是,对于一个典型的应用程序,JVM将花费越来越多的时间运行GC,最终徒劳地完成任务

第二种方法的问题是它可能会过早放弃


GC在该区域的实际行为由JVM选项(-XX:…)控制。显然,32位和64位JVM的默认行为有所不同。这样做是有道理的,因为(直观地)64位JVM的“内存不足死亡螺旋”效应将持续更长时间,并且更加明显


我的建议是不要管这个问题。除非您真的需要用东西填满内存的最后一个字节,否则JVM最好早点死,避免浪费大量时间。然后,您可以使用更多内存重新启动它并完成任务

显然,您的基准是非典型的。大多数真正的程序只是不试图抓住堆的所有部分。您的应用程序也可能是非典型的。但您的应用程序也可能存在内存泄漏问题。如果是这样的话,您应该调查泄漏情况,而不是试图找出无法使用所有内存的原因


然而,我的问题主要是为什么它不尊重我的xmx设置

它是对它的尊敬!-Xmx是堆大小的上限,而不是决定何时放弃的标准

我已经将XMX设置为2432M,但要求JVM返回其对最大内存的理解返回2162M

它返回已使用的最大内存,而不是允许使用的最大内存

为什么它“认为”最大内存比xmx少11%

见上文

此外,为什么当堆达到2006M时,它不会将堆扩展到至少2162

我认为这是因为JVM达到了“垃圾收集时间过长”的阈值