Java/MySQL插入导致OutofMemory异常

Java/MySQL插入导致OutofMemory异常,java,mysql,out-of-memory,Java,Mysql,Out Of Memory,我一直在设计一个通过PHP连接的Java服务器,它接受一系列的蛋白质链并对每一条进行计算。计算由外部Perl脚本处理,这些脚本将数据返回到Java,然后将Java插入MySQL数据库 Java成功执行Perl脚本并返回数据,问题在于MySQL插入数据。Java似乎抛出了OutofMemory异常(堆空间不足)。在谷歌搜索大多数解决方案后,似乎都涉及到“增加堆大小”,问题是10条蛋白质链将堆大小增加到500MB似乎可以解决问题,但如果再次输入20条链,堆大小将不得不增加,1000条链(系统应能处理

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

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

我的问题是

  • MySQL插入的作用是什么导致堆被填满,为什么JVM没有清理多余的数据?MySQL查询不是一个准备好的语句,只是一个简单的INSERT和executeUpdate。我们使用的是驱动程序mysql-connector-java-5.1.13-bin
启用该选项,当服务器内存不足时,使用类似的工具查看.hprof文件。MAT会告诉你谁在使用内存,它也会试图找出漏洞。

导致JVM内存崩溃的不是MySQL,只有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);
List results=new ArrayList();
对于(int i=0;i<1000;i++)
结果:添加(callPerl(蛋白质[i]);
对于(ProteinResult pr:结果)
db.执行(“插入…”,结果);
如果是这样,请将其转换为“流样式”,它一次只做一件事,并且不会超过必须的时间保留对象,并且这是完全可伸缩的:

for (int i = 0; i < 1000; i++)
    db.execute("insert into ...", callPerl(proteins[i])));
for(int i=0;i<1000;i++)
execute(“insert-into…”,callPerl(proteins[i]));
如果从表面上看代码并没有得到答案,您可以使用JVM探查器找出哪些对象正在占用内存,它与正在运行的JVM挂钩,可以告诉您诸如每秒创建多少个对象以及它们是什么类等信息。您的内存泄漏应该为探查器留下大量线索


这里有一个您可以查看的选项:

您的代码似乎在泄漏内存。请发布一些代码。当您使用VisualVM这样的内存探查器时,您会看到什么?可能是您的代码,而不是insert。您是否关闭了所有的结果集、PreparedStatements和finally块,因为这些对象永远不会被GC’ed,并一直保持在usedMemory中,直到JVM实例存在禁用它。也许您的意思是
-XX:+HeapDumpOnOutOfMemoryError
;)这些选项通常与它们的默认+/-值一起列出。;)