如何处理java.lang.OutOfMemoryError:GC开销超出正常限度?

如何处理java.lang.OutOfMemoryError:GC开销超出正常限度?,java,mysql,jsf,garbage-collection,glassfish,Java,Mysql,Jsf,Garbage Collection,Glassfish,我用Java/JSF为客户机编写了一个非常简单的报告,它基本上是根据一些简单的搜索条件(开始和结束日期等)从mysql数据库的表中返回行。这个数据库包含大量的行,但过去有一个限制,即只返回特定类型的行,这些行只占表的1%左右 最近,客户要求my在搜索条件中添加一个复选框,允许他们绕过返回行的限制。如果选中该复选框并保留较宽的日期范围,则可以尝试检索大量结果集,之后用户将被重定向到Glassfish错误页面,并显示令人愉快的消息:java.lang.OutOfMemoryError:GC开销限制

我用Java/JSF为客户机编写了一个非常简单的报告,它基本上是根据一些简单的搜索条件(开始和结束日期等)从mysql数据库的表中返回行。这个数据库包含大量的行,但过去有一个限制,即只返回特定类型的行,这些行只占表的1%左右

最近,客户要求my在搜索条件中添加一个复选框,允许他们绕过返回行的限制。如果选中该复选框并保留较宽的日期范围,则可以尝试检索大量结果集,之后用户将被重定向到Glassfish错误页面,并显示令人愉快的消息:java.lang.OutOfMemoryError:GC开销限制

我找到的每个关于这个错误的帖子的回复基本上都是“不要捕捉内存不足的错误”,我明白了原因:你无法真正预测OOM错误会在哪里出现,即使你知道它是在哪里引起的


我想知道如何比使用Glassfish错误页面更优雅地处理这个问题。理想情况下,我希望能够将用户带回搜索页面,并显示一条消息,告诉他们如果标准太宽,则缩小标准范围。在我的内存用完之前,有没有一个好方法可以做到这一点?或者是对搜索结果设置任意限制的最佳解决方案(可能首先使用count()运行查询,如果返回的值超过X,则返回带有错误消息的搜索页面?

我认为最好的方法是使用分页。用户在屏幕上能看到多少记录?比如说100。因此,您将显示前100行,并使用下100行导航到下一页。当然,这取决于业务需求

对于大小不限的结果,您应该对其进行流式处理,而不是在发送页面之前尝试完整呈现页面


例如,使用基于光标的方法和流式传输http输出。这样,服务器只需保持有限的状态,最坏情况下,用户的浏览器会因为页面太大而无法使用。

是的,这样做不是有充分理由的。它表明了一个真正的错误,而不仅仅是一个异常。您可以选择对数据进行分页、在不将其全部保存在内存中的情况下对结果进行流式处理或增加堆。对于大小不限的结果,您应该对其进行流式处理。e、 g.使用基于光标的方法,并流式传输http输出