java.lang.OutOfMemoryError: Requested array size exceeds VM limit

JAVA herman 1857浏览
公告:“业余草”微信公众号提供免费CSDN下载服务(只下Java资源),关注业余草微信公众号,添加作者微信:xttblog,发送下载链接帮助你免费下载!
本博客日IP超过1800,PV 2600 左右,急需赞助商。
极客时间所有课程通过我的二维码购买后返现24元微信红包,请加博主新的微信号:xttblog,之前的微信号好友位已满,备注:返现
所有面试题(java、前端、数据库、springboot等)一网打尽,请关注文末小程序
视频教程免费领

有些人可能写个好多年的代码,但是他不一定遇见过这个错误。java.lang.OutOfMemoryError: Requested array size exceeds VM limit 错误非常的少见,你可以在面试中问问,能说明白这个错误的绝对是认真看过 JVM 的。今天我们就说说 Requested array size exceeds VM limit (创建的数组长度超过限制)。

Java 语言其实是限制了数组的最大长度。这个不是底层 JVM 限制的,而是 Java 语言在创建数组时,就限制了数组的长度最大为 Integer.MAX_VALUE。因为数组的下标就是 int 类型的,你最大也不可能超过 Integer.MAX_VALUE。

java.lang.OutOfMemoryError: Requested array size exceeds VM limit

需要注意的是,并不是所有的操作系统和 JDK 都限制的数组的度最大长为 Integer.MAX_VALUE。比如在 64位的 MB Pro 上,Java 1.7 平台可以分配长度为 2,147,483,645, 以及 Integer.MAX_VALUE-2) 的数组。但差别不是特别的大,基本上都在 1 ~ 21亿 之间的范围。

java.lang.OutOfMemoryError: Requested array size exceeds VM limit 错误是由 JVM 中的本地代码抛出的。

在为数组分配内存之前,JVM 会执行一项检查。要分配的数据结构在该平台是否可以寻址(addressable)。如果不能寻址(addressable)就会抛出这个错误。

下面我们通过一个示例来演示 java.lang.OutOfMemoryError: Requested array size exceeds VM limit 错误。

for (int i = 3; i >= 0; i--) {
  try {
    int[] arr = new int[Integer.MAX_VALUE-i];
    System.out.format("Successfully initialized an array with %,d elements.\n", Integer.MAX_VALUE-i);
  } catch (Throwable t) {
    t.printStackTrace();
  }
}

执行上面的代码,在 64位 Mac OS X 的 Hotspot 7 平台上,就会得到类似下面这样的结果:

java.lang.OutOfMemoryError: Java heap space
  at eu.plumbr.demo.ArraySize.main(ArraySize.java:8)
java.lang.OutOfMemoryError: Java heap space
  at eu.plumbr.demo.ArraySize.main(ArraySize.java:8)
java.lang.OutOfMemoryError: Requested array size exceeds VM limit
  at eu.plumbr.demo.ArraySize.main(ArraySize.java:8)
java.lang.OutOfMemoryError: Requested array size exceeds VM limit
  at eu.plumbr.demo.ArraySize.main(ArraySize.java:8)

前面两次抛出了 Java heap space 错误。这是因为 2^31-1 个 int 数占用的内存超过了JVM默认的8GB堆内存。所以说 Requested array size exceeds VM limit 错误很少被看到。

发生 java.lang.OutOfMemoryError: Requested array size exceeds VM limit 错误的原因很可能就是你的代码问题。

数组太大,最终长度超过平台限制值,但小于 Integer.MAX_VALUE。

解决方法就是检查你的代码中是否有创建超大数组的地方。

如果确实需要处理超大数据集,那就要考虑调整解决方案了。例如拆分成多个小块,按批次加载;或者放弃使用标准库,而是自己处理数据结构,比如使用 sun.misc.Unsafe 类,通过 Unsafe 工具类可以像 C 语言一样直接分配内存。

参考资料

业余草公众号

最后,欢迎关注我的个人微信公众号:业余草(yyucao)!可加QQ1群:135430763(2000人群已满),QQ2群:454796847(已满),QQ3群:187424846(已满)。QQ群进群密码:xttblog,想加微信群的朋友,之前的微信号好友已满,请加博主新的微信号:xttblog,备注:“xttblog”,添加博主微信拉你进群。备注错误不会同意好友申请。再次感谢您的关注!后续有精彩内容会第一时间发给您!原创文章投稿请发送至532009913@qq.com邮箱。商务合作可添加助理微信进行沟通!

本文原文出处:业余草: » java.lang.OutOfMemoryError: Requested array size exceeds VM limit