cod*_*ver 2 java sql jvm memory-management out-of-memory
我正在运行代码长时间作为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();
}
Run Code Online (Sandbox Code Playgroud)
现在我想运行这个测试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.
Run Code Online (Sandbox Code Playgroud)
我将其作为多线程程序运行.所以arnd 10个线程正在进行插入.
有没有什么方法可以不用黑客的方式绕过这个程序.我的意思是,如果我决定运行15-20小时而不是8-10小时.
编辑:添加stmt.close,因为我已经在我的代码中使用它.基于评论的一些变化
谢谢
PS:抱歉,不能发布NDA的代码
基本上,我认为你正在咆哮错误的树:
无论分配速度有多快,JVM/GC 都会设法释放无法访问的对象.如果您正在运行经典的非并发GC,那么在GC释放内存之前,JVM将停止执行其他操作.如果您将JVM配置为使用并发GC,它将尝试同时运行GC和正常工作线程...并且如果无法跟上则恢复为"停止所有并收集"行为.
如果内存不足,那是因为应用程序中的某些东西(或它正在使用的库/驱动程序)正在泄漏内存.换句话说,即使您的应用程序不再需要它,某些东西也会导致对象保持可访问状态.
正如评论所指出的,您需要使用内存分析器/堆转储有条不紊地解决此问题.随机更改内容或将其归咎于GC极不可能解决问题.
(当你说"......我确实一直使用stmt.close()"时,我认为这意味着你的代码看起来像这样:
PreparedStatement stmt = ...
try {
stmt.execute();
// ...
} finally {
stmt.close();
}
Run Code Online (Sandbox Code Playgroud)
如果你不close打电话,finally那么你可能不是close每次都打电话.特别是,如果在execute调用期间或在调用与调用之间抛出某些异常close,则可能close无法调用...这将导致泄漏.)