我正在运行代码长时间作为Oracle数据库压力测试的一部分并使用java版本“1.4.2”。简而言之,我所做的是:
while(true)
{
Allocating some memory as a blob
byte[] data = new byte[1000];
stmt = fConnection.prepareStatement(query); // [compiling an insert query which uses the above blob]
stmt.execute(); // I insert this blob-row in the database.
stmt.close();
}
现在我想运行这个测试8-10小时。然而,在插入大约1500万条记录之后,显然我点击了 java.lang.OutOfMemoryError
我用-Xms512m -Xmx2g运行它。我尝试使用更高的值,但我似乎没有那么多的硬件,我认为它不是req:
java -Xms512m -Xmx4g -jar XX.jar
Invalid maximum heap size: -Xmx4g
The specified size exceeds the maximum representable size.
Could not create the Java virtual machine.
java -Xms2g -Xmx3g -jar XX.jar
Error occurred during initialization of VM
Could not reserve enough space for object heap
Could not create the Java virtual machine.
我将其作为多线程程序运行。因此,有10个线程正在进行插入。
有没有什么方法可以以不苛刻的方式绕过这个程序。我的意思是,如果我决定运行15-20小时而不是8-10小时。
编辑: 添加了stmt.close,因为我已经在我的代码中使用了它。 基于评论的一些变化
由于
P.S:抱歉无法发布NDA的代码
答案 0 :(得分:6)
基本上,我认为你正在咆哮错误的树:
无论分配速度有多快,JVM / GC 都将设法解除分配无法访问的对象。如果您正在运行经典的非并发GC,那么在GC释放内存之前,JVM将停止执行其他操作。如果您将JVM配置为使用并发GC,它将尝试同时运行GC和正常工作线程...并且如果无法跟上,则恢复为“停止所有并收集”行为。
< / LI>如果内存不足,那是因为应用程序中的某些东西(或它正在使用的库/驱动程序)正在泄漏内存。换句话说,即使您的应用程序不再需要它,某些东西也会导致对象保持可访问状态。
正如评论所指出的,您需要使用内存分析器/堆转储有条不紊地解决此问题。随机更改内容或将其归咎于GC极不可能解决问题。
(当你说“......我一直使用stmt.close()”时,我认为这意味着你的代码看起来像这样:
PreparedStatement stmt = ...
try {
stmt.execute();
// ...
} finally {
stmt.close();
}
如果您未将close
来电置于finally
,那么您可能不会每次都致电close
。特别是,如果在execute
调用期间或在close
调用之间抛出某个异常,则close
可能无法调用...这将导致泄漏。)
答案 1 :(得分:1)
我认为你应该添加
stmt.close();
因此将释放分配给preparedStatement的内存。
答案 2 :(得分:1)
如果您的代码或库中存在泄漏,则Memory Analyzer(MAT)是一个免费的基于Eclipse的应用程序,用于深入研究Java内存转储文件。说明包括如何让它为您删除转储文件。 http://www.eclipse.org/mat/
答案 3 :(得分:1)
此执行由OracleConnection NativeMemory引起。对于NIO操作oracle jdbc的人决定使用本机部分内存。很可能在执行此查询后过于频繁地使您的应用程序转储。要摆脱这种情况,您可以增加jdbc的缓存大小或以时间间隔重新启动应用程序
答案 4 :(得分:0)
java -Xms2g -Xmx3 -jar XX.jar
Error occurred during initialization of VM
Incompatible minimum and maximum heap sizes specified
尝试
java -Xms2g -Xmx3g -jar XX.jar
你的盒子里有多少记忆?您运行的是32位还是64位JVM?
答案 5 :(得分:0)
编辑:似乎可能是已知的Oracle驱动程序问题: http://www.theserverside.com/discussions/thread.tss?thread_id=10218
只是一个远景,我知道你在这里做的是简单的JDBC,但如果你有任何增强器(AspectJ,Hibernate,JPA),有一个(轻微的)Perm gen泄漏的机会,设置-XX:MaxPermGen=256m
只是为了安全起见
另外jvisualvm内存分析器和jprofiler(你可以使用试用版)会更快地指出它