繁体   English   中英

如何修复Java中“请求的数组大小超过VM限制”错误?

[英]How to fix “Requested array size exceeds VM limit” error in Java?

是否有一个日志选项可以让tomcat记录错误的查询而不是抛出这个?

SEVERE:java.lang.OutOfMemoryError:请求的数组大小超过VM限制

(尝试将日志级别设置为FULL,但仅捕获上述内容)

这还不足以进一步调试
或者,如果可以通过调整以下内容来分配更多内存来修复此问题?

-Xms1024M -Xmx4096M -XX:MaxPermSize = 256M

更新

-Xms6G -Xmx6G -XX:MaxPermSize = 1G -XX:PermSize = 512M

(以上看起来效果更好,继续监控)

我怀疑你可能在大型索引上使用排序。 这是我必须知道的一件事,Lucene需要一个大的数组大小。 无论哪种方式,您可能希望尝试使用具有以下选项的64位JVM:

-Xmx6G -XX:MaxPermSize=128M -XX:+UseCompressedOops

最后一个选项会将64位内存指针减少到32位(只要堆低于32GB)。 这通常会将内存开销降低约40%,因此可以显着延长内存。

更新:您很可能不需要如此庞大的永久代尺寸,当然不是1G。 你可能对128M很好,如果你继续使用Java 6,你会得到一个特定的错误。由于你的服务器限制为8G,你可能能够通过7G获得更小的烫发堆根。 小心不要进入交换,这会严重减慢Java的速度。

我注意到你在更新中没有提到-XX:+UseCompressedOops 如果你还没有尝试过,那可能会产生很大的不同。 你可以通过减少伊甸园的大小来挤出更多的空间,给予终身一代更大的空间。 除此之外,我认为你只需要更多的内存或更少的排序字段。

如果您想找出导致OutOfMemory的原因,您可以添加

-XX:+HeapDumpOnOutOfMemoryError 

你的java选择。

下次内存不足时,您将获得一个堆转储文件,可以使用位于jdk / lib中的“jhat”进行分析。 Jhat将向您显示堆中存在的对象以及它们消耗的内存量。

您将获得此异常,因为您正在尝试创建一个大于Java VM堆中最大连续内存块的Array。

https://plumbr.eu/outofmemoryerror/requested-array-size-exceeds-vm-limit

解决办法是什么?

java.lang.OutOfMemoryError:请求的数组大小超过VM限制可能由于以下任一情况而出现:

您的阵列变得太大,最终的大小在平台限制和Integer.MAX_INT之间

您故意尝试分配大于2 ^ 31-1元素的数组来试验限制。

在第一种情况下,检查您的代码库以确定您是否确实需要大型数组。 也许你可以减少数组的大小并完成它。 或者将阵列分成较小的块,并按照适合您的平台限制的批量加载您需要使用的数据。

在第二种情况下 - 记住Java数组是由int索引的。 因此,在平台中使用标准数据结构时,您不能超越阵列中的2 ^ 31-1个元素。 事实上,在这种情况下,编译器在编译时宣布“错误:整数太大”的编译器已经阻止了你。 但如果您真的使用真正的大型数据集,则需要重新考虑您的选择。 您可以以较小的批量加载需要使用的数据,并且仍然使用标准Java工具,或者您可能超出标准实用程序。 实现此目的的一种方法是查看sun.misc.Unsafe类。 这允许您直接分配内存,就像在C中一样。

我在catalina.sh使用它

JAVA_OPTS="-Dsolr.solr.home=/etc/tomcat6/solr -Djava.awt.headless=true -server -XX:NewSize=256m -XX:MaxNewSize=256m -XX:PermSize=256m -XX:MaxPermSize=256m -XX:+DisableExplicitGC"

我从未在Tomcat / solr上遇到过30M小文档的mem问题。 我遇到了solrJ索引客户端的问题。 我不得不为Java客户端使用-Xms8G -Xmx8G ,并通过250K文档块添加文档。

内存不足! 查看是否有数组越界,或循环系统资源被吞没!


  1. java.lang.OutOfMemoryError:Java堆空间在JVM中,如果98%的时间可用于GC堆大小,则少于2%的时间抛出此异常信息。 JVM堆设置是java程序运行的JVM内存空间,可用于部署设置。 JVM在启动时自动设置堆大小值,初始空间(即-Xms)是物理内存的1/64,最大空间(-Xmx)是物理内存的1/4 .JVM可用于提供 - 可以设置Xmn-Xms-Xmx和其他选项。

  2. 请求的数组大小超过VM限制:这是因为数组大小的应用程序超出了堆空间的大小,例如数组中的256M堆空间要申请512M

升级solr到更新的版本似乎已经解决了这个问题,可能更新的版本有更好的堆内存管理。

暂无
暂无

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

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