由于大量数据处理导致Java内存泄漏

时间:2011-10-15 01:51:48

标签: java mysql memory

我目前正在开发一个处理多个文件的应用程序,每个文件包含大约75,000条记录(以二进制格式存储)。当这个应用程序运行时(手动,大约每月一次),大约有100万条记录完全包含在文件中。文件放在一个文件夹中,单击进程然后将其存储到MySQL数据库(table_1)

记录包含需要与包含超过700k记录的另一个表(table_2)进行比较的信息。

我已经通过以下几种方式解决了这个问题:

方法1:立即导入,稍后处理

在这种方法中,我会将数据导入数据库,而无需从另一个表中进行任何处理。但是,当我想对收集的数据运行报告时,假设内存泄漏(崩溃前总共使用1 GB)会崩溃。

方法2:立即导入,使用MySQL处理

这就是我想做的事情,但在实践中它似乎并没有那么好。在这里,我将编写逻辑来查找table_1和table_2之间的相关性。然而,MySQL的结果是巨大的,我无法获得一致的输出,有时会导致MySQL放弃。

方法3:立即导入,立即处理

我目前正在尝试这种方法,虽然内存泄漏很微妙,但在崩溃之前它仍然只能获得大约200,000条记录。我一路上尝试了许多强制垃圾收集,正确地破坏了课程等等。似乎有些事情在打击我。

我正在努力解决内存泄漏/应用程序崩溃的问题。我不是Java的专家,还没有真正处理MySQL中的大量数据。任何指导都会非常有帮助。我已经考虑过这些方法:

  • 将每个行进程分解为单独的类,希望能够在每行中删除任何内存使用情况
  • 某种存储过程,一旦一行存储到数据库中,MySQL就会执行table_1< => table_2计算并存储结果

但我想向许多熟练的Stack Overflow成员提出问题,以便正确了解应该如何处理。

4 个答案:

答案 0 :(得分:3)

我同意“使用分析器”的答案。

但我想在你的问题中指出一些误解:

  • 存储泄漏不是由于海量数据处理造成的。这是由于一个错误。 “重量级”只会使症状更明显。

  • 运行垃圾收集器无法解决存储泄漏问题。 JVM 总是在它决定放弃并抛出OOME之前立即运行完整的垃圾收集。


如果没有关于您尝试做什么以及如何做的更多信息,很难就可能导致存储泄漏的原因提供建议。

答案 1 :(得分:2)

VirtualVM这样的探查器的学习曲线非常小。幸运的话,你会在一个小时左右的时间里找到答案 - 至少是一个非常大的线索。

答案 2 :(得分:0)

你可以通过以下方式妥善处理这种情况:

  • 在应用程序崩溃并在良好的内存分析器中分析时生成堆转储
  • 将正在运行的应用程序连接到一个好的内存分析器并查看堆

我个人更喜欢yjp,但也有一些不错的免费应用程序(例如jvisualvm和netbeans)

答案 3 :(得分:0)

在不了解你正在做什么的情况下,如果你的内存不足,你可能会将某些内容存储在jvm中,但是你应该可以像这样做一个数据处理任务你遇到的严重的记忆问题。在过去,我已经看到数据处理管道内存不足,因为有一个类读取数据库中的东西,将它全部包装在一个很好的集合中,然后将它传递给另一个,这当然需要所有的数据同时存在于内存中。框架很适合隐藏这类东西。

使用virtualVm进行堆转储/挖掘对我来说并不是非常有用,因为我正在寻找的细节经常被隐藏 - 例如如果你有大量的内存填充了字符串的映射,那么告诉你字符串是你内存使用中最大的组件并不是真的有帮助,你需要知道谁拥有它们。

您可以发布有关您尝试解决的实际问题的更多详细信息吗?