问题是,一旦调用rs.close(),它将释放从内存中删除获取的记录的权限吗? 要么 当JVM面临空间不足时,将调用垃圾回收器删除resultSet吗?
如果JVM在遇到内存不足时正在调用GC,那么在Java程序中手动调用Garbage收集器以释放空间是一种好习惯吗?
答案 0 :(得分:1)
结果集通常通过使用数据库 cursor 来实现。调用resultSet.close()
将释放该游标,因此它将立即释放数据库中的资源 。
结果集读取的数据通常在记录的块中接收。调用resultSet.close()
可能会“释放”最后一个块,使其符合GC的条件,但是一旦resultSet
本身超出范围并符合GC的条件,无论如何都会发生,并且可能在调用后立即发生close()
,因此调用close()
提前释放Java内存真的没关系。
Java内存只能通过GC运行来释放。您无法控制何时发生(调用System.gc()
只是提示,您没有控制权。)
您正在考虑错误的事情。您应该关注的是:
确保始终关闭资源 1 ,以释放数据库和系统资源。
最好使用 try-with-resources 。
确保您不要保留太多数据,例如如果可以在获取数据时对其进行处理,则不要为检索到的每一行创建对象。
这通常是发生内存泄漏,而不是在JDBC驱动程序内部。
1)例如ResultSet
,Statement
,Connection
,InputStream
,OutputStream
,Reader
,Writer
等。 >
答案 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。