2

我正在尝试使用 JDBC 从数据库创建转储文件。该文件的大小应约为 300 mb,包含 10 列中的 1.2 到 150 万条记录,但我在大约 250000 处内存不足。

我的问题是 java 是否将整个记录集存储在内存中?我已将记录集设置为只能向前读取,希望已转储的记录将从内存中清除,但似乎并非如此。

任何帮助将不胜感激。

4

4 回答 4

7

您应该setFetchSizeStatement对象上使用。以下示例一次只能从 a 获取 1000 条记录ResultSet

Connection con = DriverManager.getConnection("jdbc:my_subprotocol:my_subname");
Statement stmt = con.createStatement();
stmt.setFetchSize(1000);
ResultSet rs = stmt.executeQuery("SELECT * FROM your_table");

这是Javadoc:

http://java.sun.com/javase/6/docs/api/java/sql/Statement.html#setFetchSize(int)

于 2009-08-25T10:37:28.150 回答
1

如果您要检索所有数据,然后作为第二步写入文件,那么所有 db 数据都在内存中。如果您将数据流式传输到文件,则不会发生这种情况。即,而不是

data=...
while (rs.next()){
  ... add rs value to data
}
..write data to file

就像是

file=...
while (rs.next()){
  write rs to file
}
于 2009-08-25T14:28:07.290 回答
0

设置 fetchSize 应该会有所帮助。但实际上它取决于 jdbc 驱动程序。但是您可以迭代地读取数据(按小部分):

stm = conn.prepareStatement("...where id > ? order by id");
stm.setMaxRows(100);

while(true) {
    stm.setInt(1, lastId);
    ResultSet results = stm.executeQuery();

    // process results and assign a new value to lastId 

    rs.close();
}
于 2009-08-25T19:15:20.147 回答
0

获取缓冲区/释放行为取决于 JDBC 驱动程序以及 JVM 的垃圾收集器。在写入 FileOutputStream 之前你是否在做任何缓冲(这可能会阻止你的内存被垃圾收集)?

尝试使用-Xms-Xmxjava 运行时参数调整 Java 堆大小。例子:

java -Xms1024M -Xmx1024M com.mypkg.MyResultSetReader

上面的命令将为您的程序提供 1GB 的堆空间。如果这是一个临时工具,或者您不希望 ResultSet 大小增加,这可能是一个永久的解决方案。

于 2009-08-25T14:13:31.760 回答