我的代码中的内存不足exception

我正在运行代码长时间作为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. 

我将其作为multithreading程序运行。 所以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调用之间抛出某些exception,则可能不会调用close …这将导致泄漏。)

我想你应该补充一下

 stmt.close(); 

所以分配给preparedStatement的内存将被释放。

如果您的代码或库中存在泄漏,则Memory Analyzer(MAT)是一个免费的基于Eclipse的应用程序,用于深入研究Java内存转储文件。 说明包括如何让它为您删除转储文件。 http://www.eclipse.org/mat/

此执行由OracleConnection NativeMemory引起。 对于NIO操作oracle jdbc家伙决定使用本机部分内存。 很可能在执行此查询后过于频繁地使您的应用程序转储。 要摆脱这种情况,您可以增加jdbc的缓存大小或按时间间隔重新启动应用程序

 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(您可以使用试用版)将更快地指出它