即使没有内存,我也会遇到java.lang.OutOfMemoryError吗?

即使没有内存,我也会遇到java.lang.OutOfMemoryError吗?,第1张

即使没有内存,我也会遇到java.lang.OutOfMemoryError吗?

带有HotSpot VM的Java SE
6
报价故障排除指南

3.1.3详细信息:(行

Requested array size exceeds VM limit
内粗体为我的):

详细消息

Requested array size exceeds VMlimit
表明应用程序(或该应用程序使用的API)尝试分配大于堆大小的数组。例如,如果应用程序尝试分配512MB的数组,但最大堆大小为256MB,
OutOfMemoryError
则将抛出原因
Requestedarray size exceeds VM limit
。在大多数情况下,问题可能是 配置问题 (堆大小太小),或者
是导致应用程序尝试创建大数组的错误 ,例如,当使用计算算法来计算数组中的元素数时尺寸不正确。


更新:在 @Pacerier的 鼓励下,我进行了一些快速测试。我编写了一个示例程序:

public class VmLimitTest {    public static final int SIZE = 2;    public static void main(String[] args) throws InterruptedException {        while(true) { byte[] a = new byte[SIZE * 1024 * 1024]; TimeUnit.MILLISECONDS.sleep(10);        }    }}

并使用以下JVM选项运行它:

-Xms192m -Xmx192m -XX:NewRatio=2 -XX:SurvivorRatio=6 -XX:+PrintGCDetails

这是他们的意思:

  • 整个堆为192 MiB(
    -Xms192m -Xmx192m
  • 年轻一代(eden +幸存者)空间为64 MiB,老一代为128 MiB(
    -XX:NewRatio=2
  • 每个幸存者空间(两个)为8 MiB,因此伊甸园剩下48 MiB(比率为1:6
    -XX:SurvivorRatio=6

在测试时,我发现了以下内容:

  • 如果新创建的数组可以放入eden(小于48 MiB),则程序运行正常
  • 令人惊讶的是,当数组大小超过eden大小,但可以放入eden和 一个 幸存者空间(介于48和56 MiB之间)时,JVM可以在eden和Survivor上分配单个对象(重叠两个区域)。整齐!
  • 一旦阵列大小超过eden +单个幸存者(高于56 MiB),新创建的对象将绕过eden和幸存者空间而直接放置在旧世代中。这也意味着突然之间一直在执行完整的GC-非常糟糕!
  • 我可以轻松分配127 MiB的数据,但是尝试分配129 MiB 会抛出 异常
    OutOfMemoryError: Java heap space

这是底线-您不能创建尺寸大于上一代的对象。尝试这样做将导致

OutOfMemoryError: Java heapspace
错误。那么,我们
Requested array size exceeds VM limit
什么时候可以期望可怕呢?

我尝试使用更大的对象运行同一程序。达到阵列长度限制后,我切换到

long[]
了该端口,可以轻松达到7 GiB。使用128
MiB的最大堆声明了JVM仍在抛出
OutOfMemoryError: Java heapspace
(!),我设法触发
OutOfMemoryError: Requested array size exceeds VMlimit
错误,试图在单个对象中分配8 GiB。我在具有3 GiB物理内存和1 GiB交换的32位Linux计算机上对此进行了测试。

话虽这么说,您可能永远都不会遇到此错误。该文档似乎不准确/已过时,但确实有一个结论: 这可能是一个错误, 因为创建如此大的数组非常罕见。



欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5439618.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-11
下一篇 2022-12-11

发表评论

登录后才能评论

评论列表(0条)

保存