[英]Out of memory exception in my code
我正在运行代码长时间作为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.
我将其作为多线程程序运行。 所以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();
}
如果你不把close
通话的finally
则是可能的,你是不是叫close
每一次。 特别是,如果在execute
调用期间或在它与close
调用之间抛出某些异常,则可能无法调用close
...这将导致泄漏。)
此执行由OracleConnection NativeMemory引起。 对于NIO操作oracle jdbc的人决定使用本机部分内存。 很可能在执行此查询后过于频繁地使您的应用程序转储。 要摆脱这种情况,您可以增加jdbc的缓存大小或按时间间隔重新启动应用程序
我想你应该补充一下
stmt.close();
所以分配给preparedStatement的内存将被释放。
如果您的代码或库中存在泄漏,则Memory Analyzer(MAT)是一个免费的基于Eclipse的应用程序,用于深入研究Java内存转储文件。 说明包括如何让它为您删除转储文件。 http://www.eclipse.org/mat/
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?
编辑:似乎它可能是已知的Oracle驱动程序问题: http : //www.theserverside.com/discussions/thread.tss?thread_id = 10218
只是一个远景,我知道你在这里做了简单的JDBC,但如果你有任何增强器(AspectJ,Hibernate,JPA),有一个(轻微的)Perm gen泄漏的机会,设置-XX:MaxPermGen=256m
只是为了在安全方面
此外,jvisualvm内存分析器和jprofiler(您可以使用试用版)将更快地指出它
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.