在JDBC中关闭ResultSet后的内存/堆状态

时间:2019-06-04 15:55:25

标签: java jdbc garbage-collection

  1. ResultSet从数据库中获取记录。
  2. 使用结果集对象后,我们最终关闭结果集。

问题是,一旦调用rs.close(),它将释放从内存中删除获取的记录的权限吗? 要么 当JVM面临空间不足时,将调用垃圾回收器删除resultSet吗?

如果JVM在遇到内存不足时正在调用GC,那么在Java程序中手动调用Garbage收集器以释放空间是一种好习惯吗?

3 个答案:

答案 0 :(得分:1)

结果集通常通过使用数据库 cursor 来实现。调用resultSet.close()将释放该游标,因此它将立即释放数据库中的资源

结果集读取的数据通常在记录的中接收。调用resultSet.close()可能会“释放”最后一个块,使其符合GC的条件,但是一旦resultSet本身超出范围并符合GC的条件,无论如何都会发生,并且可能在调用后立即发生close(),因此调用close()提前释放Java内存真的没关系。

Java内存只能通过GC运行来释放。您无法控制何时发生(调用System.gc()只是提示,您没有控制权。)

您正在考虑错误的事情。您应该关注的是:

  • 确保始终关闭资源 1 ,以释放数据库系统资源。

    最好使用 try-with-resources

  • 确保不要保留太多数据,例如如果可以在获取数据时对其进行处理,则不要为检索到的每一行创建对象。

    这通常是发生内存泄漏,而不是在JDBC驱动程序内部。

1)例如ResultSetStatementConnectionInputStreamOutputStreamReaderWriter等。

答案 1 :(得分:0)

ResultSet.close()将立即释放所有资源,但Blob,Clob和NClob对象除外。 Release 表示垃圾收集器决定释放资源。通常我们不必为此担心。

但是,JDBC使用的某些内存可能仍会使用。 假设驱动程序内置了某种缓存,并且该缓存是连接作用域的。要释放该内存,您必须关闭JDBC连接。

例如MySQL JDBC的默认访存大小为0,这意味着它将整个表加载到内存中,并将其保存在内存中以供所有语句使用。此内存缓冲区的范围是什么? ;)

无论如何,如果您怀疑内存问题,请查看JDBC驱动程序的详细信息。

经验法则,显式GC绝不是好主意。但是为了快速确定ResultSet.close()/ Connection.close()是否释放任何资源,请尝试一下:检查已使用/可用的内存,close(),gc(),然后再次检查内存。没有显式GC,您几乎看不到任何变化。

答案 2 :(得分:0)

显式GC是JVM的负担,因为它必须经常检查内存使用情况并决定何时触发它。在这种情况下,根据应用程序要求设置适当的GC就足以应付上述情况。

ResultSet.close将标记用于垃圾回收的资源,即释放引用以将内存块标记为不可访问。另外,对于jdbc,需要关闭连接,以便保留连接缓存的内存也可以标记为gc。