Java / MySQL插入导致OutofMemory异常

时间:2011-07-16 00:08:49

标签: java mysql out-of-memory

我一直在设计一个通过PHP连接的Java服务器,它接受一系列蛋白质链并对它们进行计算。计算由外部Perl脚本处理,外部Perl脚本将数据返回到Java,然后插入到MySQL数据库中。

Java成功执行Perl脚本并返回数据,问题在于MySQL插入数据。 Java似乎抛出了OutofMemory异常(用完了堆空间)。谷歌搜索后大多数解决方案似乎涉及“增加堆大小”,这个问题是10个蛋白质链增加堆大小到500MB似乎解决了问题,但如果再次输入20个链,堆大小将不得不增加和1000个链(系统应该能够处理的)增加堆大小不是一种选择。

我的问题是这个。

  • 什么是MySQL INSERT正在做什么导致堆填充,为什么JVM没有清理多余的数据? MySQL查询不是预处理语句,只是一个简单的INSERT和executeUpdate。我们使用的是mysql-connector-java-5.1.13-bin驱动程序。

2 个答案:

答案 0 :(得分:3)

启用-XX:+HeapDumpOnOutOfMemoryError选项,当服务器内存不足时,使用Eclipse MAT等工具查看.hprof文件。 MAT会告诉你谁正在使用内存,它也会尝试找出漏洞。

答案 1 :(得分:0)

不会是MySQL导致JVM中的内存井喷 - 只有in-JVM操作可以做到这一点。

你的代码可能是“块方式”完成的,看起来像这个伪代码:

List<ProteinResult> results = new ArrayList<ProteinResult>();
for (int i = 0; i < 1000; i++)
    results.add(callPerl(proteins[i]));

for (ProteinResult pr : results)
    db.execute("insert into ...", results);

如果是这样的话,把它变成一种“流式”,它一次做一件事并且不会长时间保持对象,这是完全可扩展的:

for (int i = 0; i < 1000; i++)
    db.execute("insert into ...", callPerl(proteins[i])));

如果以面值查看代码不会产生答案,您可以通过使用JVM分析器找出哪些对象正在咀嚼内存,JVM分析器挂接到正在运行的JVM并且可以告诉您有多少对象是每秒创建的,它们是什么类等等。你的内存泄漏应该留下足够的线索让分析器找到。

以下是您可以查看的内容:JProfiler