作为 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 运行它。我尝试使用更高的值,但我似乎没有那么多硬件,我也不认为这是必需的:
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 因为我已经在代码中使用了它。
根据评论进行一些更改
Thanks
P.S:抱歉,由于 NDA,无法发布代码
基本上,我认为你找错了树:
JVM/GCwill设法释放无法访问的对象,无论您分配它们的速度有多快。如果您正在运行经典的非并发 GC,那么 JVM 将停止执行其他操作,直到 GC 释放内存为止。如果您将 JVM 配置为使用并发 GC,它将尝试同时运行 GC 和普通工作线程……如果无法跟上,则恢复为“停止一切并收集”行为。
如果您的内存不足,那是因为您的应用程序(或其正在使用的库/驱动程序)中的某些内容正在泄漏内存。换句话说,某些因素导致对象保持可访问性,即使您的应用程序不再需要它们。
正如评论所指出的,您需要使用内存分析器/堆转储系统地解决此问题。随机更改内容或将其归咎于 GC 不太可能解决问题。
(当你说“...我确实一直使用 stmt.close()”,我认为这意味着您的代码如下所示:
PreparedStatement stmt = ...
try {
stmt.execute();
// ...
} finally {
stmt.close();
}
如果你不把close
打电话来finally
那么你可能没有打电话close
每次。特别是,如果在执行过程中抛出一些异常execute
或在它和之间调用close
调用,那么有可能close
不会被调用......这将导致泄漏。)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)