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

是否有一个日志选项可以让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将向您显示堆中存在的对象以及它们消耗的内存量。

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

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

解决办法是什么?

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

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

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

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

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

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


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

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

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

我在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文档块添加文档。