【问题标题】:OutOfMemory when Migration DB to DB将 DB 迁移到 DB 时出现 OutOfMemory
【发布时间】:2019-07-19 04:54:38
【问题描述】:

我制作了用于将 DB 迁移到 DB 的 java 程序。 这会产生 oom。 我该怎么做才能返回内存?

我返回垃圾收集器。 所以,我看到我正在使用的内存正在缩小。 但是,当数据量很大时,垃圾收集并没有帮助。

    private void insertIntoTable(Connection con, ResultSet rs, String targetTable) {
        PreparedStatement pstmt = null;
        int batchSize = 50000;
        String insertSql = createInsertSql(targetTable);
        Blob blob = null;

        try {
            pstmt = con.prepareStatement(insertSql);

            int i = 0;
            while (rs.next()) {
                i++;
                int j = 0;
                for (String key : colMap.keySet()) {
                    if (colMap.get(key).contains("TIMESTAMP")) {
                        pstmt.setTimestamp(++j, rs.getTimestamp(key));
                    } else if (colMap.get(key).contains("DATE")) {
                        pstmt.setDate(++j, rs.getDate(key));
                    }  else if (colMap.get(key).contains("BLOB")) {
                        if(blob==null) {
                            blob = con.createBlob();
                        }
                        blob.setBytes(1, rs.getBytes(key));
                        pstmt.setBlob(++j, blob);
                    } else {
                        pstmt.setString(++j, rs.getString(key));
                    }
                }

                pstmt.addBatch();// addBatch에 담기
                pstmt.clearParameters();// 파라미터 Clear

                if ((i % batchSize) == 0) {
                    System.out.print("★");
                    pstmt.executeBatch();
                    pstmt.clearBatch();
                    con.commit();
                }
            }
            System.out.println("★\ncount:\t" + i);
            System.out.println();
            pstmt.executeBatch();
            con.commit();
        } catch (SQLException e) {
            e.printStackTrace();

            try {
                con.rollback();
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
        } finally {
            if (rs != null)
                try {
                    rs.close();
                    rs = null;
                } catch (SQLException ex) {
                }
            if (pstmt != null)
                try {
                    pstmt.close();
                    pstmt = null;
                } catch (SQLException ex) {
                }
        }
    }

我想迁移内存返回的大量数据一次效果很好。

【问题讨论】:

  • 减少批处理大小,或增加 Java 进程的内存。或两者兼而有之。

标签: java sql oracle jdbc


【解决方案1】:

这是因为批量太大。

解决方案:
有一种方法可以定义最大批量大小,但问题是大多数数据库驱动程序都没有实现该方法。

因此,您需要维护 .addBatch() 和方法调用的计数,然后需要根据应用程序资源容量在 100 或 1000 的计数上执行该批处理。

所以,这里的问题是批量太大(50000)

【讨论】:

  • 服务器CPU核心为12,内存为503G。而且1000的batch size比50000的时候要慢。我要处理1000万的数据迁移。
  • @vine-nam,我认为在这种情况下,如果可能的话,使用 SQL 脚本而不是使用 java 作为中间脚本更合适。
猜你喜欢
  • 2012-08-01
  • 1970-01-01
  • 2013-09-28
  • 1970-01-01
  • 2013-01-02
  • 2019-10-07
  • 1970-01-01
  • 2019-06-23
  • 1970-01-01
相关资源
最近更新 更多