首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >超出了java jdbc preparedStatement的OutOfMemoryError GC开销限制

超出了java jdbc preparedStatement的OutOfMemoryError GC开销限制
EN

Stack Overflow用户
提问于 2014-11-20 15:22:25
回答 3查看 5.3K关注 0票数 3

我正在写一个工具,用于将数据从旧模式转换到oracle数据库中的新模式。

在我的数据库中大约有20个表。它们中只有两个是大的,它们可能有400万条记录。其他的很小(可能是一万或十万)。

现在我用一个线程来连续处理所有的小表,把大表分成几个块,创建一些线程,用一个线程处理一块,每一块就是一百万条记录。

现在我遇到了一些问题。当我启动程序时,一切都很好。但是当我的程序在一段时间后运行时,我会得到一些错误信息:

代码语言:javascript
复制
Exception in thread "Thread-8" java.lang.OutOfMemoryError: GC overhead limit exceeded
at oracle.jdbc.driver.OracleBlobInputStream.needBytes(OracleBlobInputStream.java:168)
at oracle.jdbc.driver.OracleBufferedStream.readInternal(OracleBufferedStream.java:178)
at oracle.jdbc.driver.OracleBufferedStream.read(OracleBufferedStream.java:147)
at oracle.jdbc.driver.OracleBufferedStream.read(OracleBufferedStream.java:137)
at oracle.jdbc.driver.BlobAccessor.getBytes(BlobAccessor.java:249)
at oracle.jdbc.driver.OracleResultSetImpl.getBytes(OracleResultSetImpl.java:714)
at oracle.jdbc.driver.OracleResultSet.getBytes(OracleResultSet.java:1625)
at datatransfer.processor.CProcessor.write(CProcessor.java:111)
at datatransfer.processor.Processor.process(Processor.java:77)
at datatransfer.thread.CThread.run(CThread.java:37)

我已经检查了我的程序,没有闭环,我真的关闭了statementresultset

每个Thread都有自己的Connection

我如何检查我的程序占用内存的原因?有没有办法解决这个问题呢?

代码语言:javascript
复制
    ResultSet rs = statement.executeQuery(sql);
    int count = 0;
    long start = System.currentTimeMillis();
    while(rsSrc.next()){
        preStatement.setString(1, rsSrc.getString(1)); 
        preStatement.setString(2, rsSrc.getString(2)); 
        preStatement.setString(3, rsSrc.getString(3)); 
        preStatement.setString(4, rsSrc.getString(4)); 
        preStatement.setString(5, rsSrc.getString(5)); 
        preStatement.setString(6, rsSrc.getString(6)); 
        preStatement.addBatch();
        count++;
        if (count % batchSize == 0){
            preStatement.executeBatch();
            preStatement.clearBatch();

        }
    }
    preStatement.executeBatch();
    preStatement.clearBatch();
    writeConn.commit();
    long end = System.currentTimeMillis();

statementpreStatement是由不同的Connection创建的,一个是旧模式,另一个是新模式。

我的代码中有什么地方错了吗?

EN

回答 3

Stack Overflow用户

发布于 2014-11-20 16:03:05

尝试使用jvisualvm分析RAM中的实例/对象创建,它通常会立即告诉您是否存在泄漏。(这是图形用户界面,不要惊慌;-)

文档-> https://docs.oracle.com/javase/6/docs/technotes/tools/share/jvisualvm.html

它是一个分析器,所以它会告诉你你把时间花在了哪里,你有多少个类的实例,以及你的应用程序运行时发生了什么。

它默认安装在linux上的官方oracle jdk中!

如果内存使用率几乎不变,但在边缘,请尝试增加堆(例如-Xmx2G)

票数 1
EN

Stack Overflow用户

发布于 2016-07-14 23:16:54

在我的例子中,我不得不从Matlab向DB发出成百上千条INSERT语句。我还得到了GC开销异常:

代码语言:javascript
复制
java.sql.SQLException: java.lang.OutOfMemoryError: GC overhead limit exceeded

我的解决方案是,每隔几千次(在本例中为2000次)插入快照关闭一次数据库连接,从Matlab工作区中删除并清除对象。当然,为了随后打开新的连接。

代码语言:javascript
复制
classdef MySqlService < handle    
    properties
        db;
        counter = 0;
        dblimit = 0;
    end    
    methods
        function x = executeQuery(obj, query)
            obj.counter = obj.counter + 1;
            if (obj.counter > obj.dblimit + 2000)
                obj.dblimit = obj.counter;

                delete(obj.db);
                clear obj.db;                
                import lib.queryMySQL.src.edu.stanford.covert.db.MySQLDatabase;
                obj.db = MySQLDatabase('localhost:3306', 'fani_dev', 'root', 'dev1');
            end
            obj.db.prepareStatement(query);
            x = obj.db.query();
        end
        function obj = MySqlService()
            import lib.queryMySQL.src.edu.stanford.covert.db.MySQLDatabase;
            obj.db = MySQLDatabase('localhost:3306', 'fani_dev', 'root', 'dev1');
        end
    end    
end

脚本现在可以正常工作了。此外,CPU工作负载和RAM使用率似乎也不错。

票数 1
EN

Stack Overflow用户

发布于 2014-11-20 16:18:30

这个问题的一种可能的解决方案是增加Eclipse可用的堆大小。您可以在打开位于eclipse安装文件夹中的eclipse.ini文件时执行此操作。

打开文件后,您可以添加-Xmx2048M,这将为您的Eclipse提供2 GB的堆。

这个解决方案取决于您的系统有多强大,以及您可以将整个堆的多少内容提供给Eclipse。

For more information click here...

处理这个问题的另一种方法是尝试处理大表的小块(块)。

如果你想找出更深层次的原因,你可以创建一个堆转储(或者几个堆转储),然后使用http://www.eclipse.org/mat/分析它。它是一个非常强大的工具。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27033954

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档