我的代码中的内存不足异常

时间:2010-12-13 01:07:49

标签: java sql memory-management jvm 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();

}

现在我想运行这个测试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的代码

6 个答案:

答案 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(你可以使用试用版)会更快地指出它