如何解决java.lang.OutOfMemoryError: Java heap space错误而不增加堆内存大小

3

我知道关于java.lang.OutOfMemoryError: Java heap space的问题有很多。

比如问题1

但是这些链接都不能正确回答我的问题。

我们正在生成电子表格格式的报告,其中大量数据来自数据库。我们将堆内存大小从2 GB增加到4 GB,但并没有用。

可能是由于数据库列中存在一些额外的空间,所以我使用trim()方法修剪了所有的getterssetters,但这也没有用。

例如:

String s = "Hai       ";
s.trim();

如果有人知道如何从Java编码方面解决此问题,而不增加堆空间的大小。因为客户告诉我们,他们将不会再增加堆空间。

调用该方法时出现异常

private CrossTabResult mergeAllListsSameNdc(CrossTabResult crt, CrossTabResult res) {

        crt.setFormularyTier(crt.getFormularyTier()==null ? "":((crt.getFormularyTier().contains(crt.getListId())? crt.getFormularyTier(): crt.getListId()+crt.getFormularyTier()) +"~"+res.getListId()+res.getFormularyTier()));
        crt.setFormularyTierDesc(crt.getFormularyTierDesc()==null ? "":((crt.getFormularyTierDesc().contains(crt.getListId())? crt.getFormularyTierDesc(): crt.getListId()+crt.getFormularyTierDesc()) +"~"+res.getListId()+res.getFormularyTierDesc()));}

由于保密原因,我不能分享更多的代码。如果您在查看上面的代码后有任何替代解决方案,请告知我。我们正在基于相同的id合并两个String


1
你能提供更多的代码吗? - notanormie
2
尝试分批获取数据。我猜为了经历这个问题,你必须一次性从数据库中将所有数据获取到应用服务器中。 - alexd
@notanormie,我已经在问题中附上了示例代码。 - Arvind Katte
@alexd 是的,我们通过调用 store_proc 一次性获取所有数据。 - Arvind Katte
{btsdaf} - Ravipati Praveen
1个回答

2
我们正在以电子表格格式生成报告,其中大量数据来自数据库端。
在这种情况下,有至少两件事需要研究,可以改善所消耗的内存,但首先必须确定罪魁祸首。
通常由监视工具在此用例中识别的主要原因包括:
1)如果从数据库加载的数据被识别为占用大量内存的操作,则可能不应一次性加载所有数据。将所有这些对象保存在内存中,并同时从这些数据创建电子表格,可能会消耗大量内存。特别是如果该应用程序同时用于其他用例。您应该将检索分成多个检索。然后调用一个检索以检索某些对象,填充电子表格并释放这些不再需要的对象。依此类推...
2)在创建电子表格期间,如果使用库创建的电子表格对象被识别为内存消耗巨大的对象,则应优先使用流API或事件API通过API编写电子表格,以避免加载整个电子表格而消耗大量内存。例如,POI提供类似DOM的API:XSSF和流API:SXSSF。您没有指定用于创建电子表格的库,但对于任何人来说,应当使用相同的逻辑进行处理。

我同意第一个观点。但是现在代码已经进入生产级别,我们不能更改数据结构了,对吧? - Arvind Katte
2
@ArvindKatte,如果你不改变任何东西,什么都不会得到解决。 - M. Prokhorov
今天我们有客户电话会议,让我们看看他们会采取什么方法。 - Arvind Katte
你的第一种方法对我很有帮助,我创建了一个临时变量,然后将值写入工作表,最后清除了临时变量的内存。客户同意这种方法。 - Arvind Katte

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