Java堆空间异常 java.lang.OutOfMemoryError

4

我正在开发一款抄袭检测应用程序,其中涉及大量文档处理。为了索引文档,我使用Apache Lucene,并使用Apache Solr作为文档服务器。我使用Jasper Reporting作为报告模块。在处理所有文档并检测到抄袭后,我调用使用Jasper Reporting开发的接口,此时会出现java堆空间异常。我尝试在应用程序中增加堆空间,但仍然抛出相同的异常。是否有任何建议帮助我解决这个问题。

Exception in thread "AWT-EventQueue-0" java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Arrays.java:2760)
at java.util.Arrays.copyOf(Arrays.java:2734)
at java.util.ArrayList.ensureCapacity(ArrayList.java:167)
at java.util.ArrayList.add(ArrayList.java:351)
at reportingModule.PeerSearchUI.generateResults(PeerSearchUI.java:901)
at reportingModule.PeerSearchUI.setResultDetails(PeerSearchUI.java:833)
at gui.form.WizardForm.ViewButtonActionPerformed(WizardForm.java:1372)
at gui.form.WizardForm.access$1200(WizardForm.java:50)
at gui.form.WizardForm$13.actionPerformed(WizardForm.java:870)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1995)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2318)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:236)
at java.awt.Component.processMouseEvent(Component.java:6038)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3260)
at java.awt.Component.processEvent(Component.java:5803)
at java.awt.Container.processEvent(Container.java:2058)
at java.awt.Component.dispatchEventImpl(Component.java:4410)
at java.awt.Container.dispatchEventImpl(Container.java:2116)
at java.awt.Component.dispatchEvent(Component.java:4240)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4322)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:3986)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:3916)
at java.awt.Container.dispatchEventImpl(Container.java:2102)
at java.awt.Window.dispatchEventImpl(Window.java:2429)
at java.awt.Component.dispatchEvent(Component.java:4240)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:273)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:183)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:173)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:168)

减少你使用的内存量?考虑到提供的信息,我不确定还能说什么。我们能否获得关于你的代码如何工作的更多细节?我们真的能够看到一些代码吗? - Ken Wayne VanderLinde
你能同时粘贴异常跟踪吗?它可能在开头有更多细节,指出哪个对象堆的区域正在耗尽。 - ring bearer
1
增加那个值!例如尝试1536M。512可能是一个非常低的值。 - João Fernandes
@ring bearer:我修改了问题,包括异常跟踪。 - KasunKP
1
你正在运行哪个版本的Java?java -version - crowne
显示剩余5条评论
2个回答

7

根据您的异常,错误与堆相关(不是PermGen或任何其他特定空间),因此唯一需要调整的参数将是-Xmx,以下是我的建议:

使用-Xmx让JVM使用更多内存-尝试1G:-Xmx1024m

如果这导致出现相同的错误,

  • 使用参数-XX:+HeapDumpOnOutOfMemoryError启动JVM,当程序发生OOM时会生成一个堆转储。
  • 使用像visualVM这样的工具来分析获得的堆转储。这将有助于识别内存泄漏。

除此之外,没有通用的解决方案来解决java.lang.OutOfMemoryError: Java heap space - 它可能非常应用程序特定。


3

请告诉我们您用于存储文档索引和报告结果的变量类型。

尝试将报告应用程序在单独的JVM中运行,与文档索引过程分离。

索引文档是一项资源密集型操作,如果它在索引期间持有所有使用的内存,然后尝试查询报告的索引,那么它可能会消耗更多内存。

让我们从栈跟踪最上面开始看。前三行(反向阅读)展示了问题所在。

Exception in thread "AWT-EventQueue-0" java.lang.OutOfMemoryError: Java heap space at     
java.util.Arrays.copyOf(Arrays.java:2760) at java.util.Arrays.copyOf(Arrays.java:2734) at 
java.util.ArrayList.ensureCapacity(ArrayList.java:167) at java.util.ArrayList.add(ArrayList.java:351) at 

JVM是Java虚拟机的缩写。

  1. 检查数组大小是否足够
  2. 尝试复制数组(当增加向量时的默认行为)
  3. 耗尽可用内存并抛出OutOfMemoryError异常

堆栈跟踪未提及确切的数组,但必须是一个大数组。

问题:您将完成的索引存储在哪里?报告结果放在哪里?由于您没有说明结构,我暂且假设使用Vector,这在您不知道有多少数据时很方便,但在容量增加时非常浪费。如果没有另外指定,它每次需要更多空间时都会将其大小加倍,因此100字节的初始大小很快就可以变成数十兆字节,其中几乎有一半的新空间为空。

下面两行是您报告代码中的内容。我认为UI的报告模块引用了填充数据的数组/向量/列表。请告诉我们它是什么类型。

reportingModule.PeerSearchUI.generateResults(PeerSearchUI.java:901) at  
reportingModule.PeerSearchUI.setResultDetails(PeerSearchUI.java:833) at 

下面这行代码暗示着异常发生在你点击一个按钮之后,可能是“查看结果”按钮,它会启动一个报告。
gui.form.WizardForm.ViewButtonActionPerformed(WizardForm.java:1372) at 

这意味着结果已经可用并等待显示。如果是这样,那么您需要更好的方法来隔离结果。
如何一次只显示一页结果?只显示前10行,然后显示下一个10行,以此类推。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接