将流类或连接视为 Java 中的资源泄漏

2022-01-16 00:00:00 garbage-collection java resource-leak

Java 没有对象的生命周期,这由 garbage collector 管理.如果我使用一些 IO 类而不关闭它,或者一些 DBConnection,这会被认为是资源泄漏吗?换句话说,IO对象是否会被垃圾收集器AFAIK收集和销毁,垃圾收集器仅用于内存.例如:

Java has no lifetime for an object, this is managed by the garbage collector. And if I use some IO classes without closing it, or some DBConnection, will this considered a resource leak? In another words, will IO object be collected and destroyed by garbage collector, AFAIK, the garbage collector is for memory only. For example:

BufferedReader br = new BufferedReader( new FileReader( new File("path") ) );

推荐答案

是的,你是对的.

垃圾收集释放 Java 堆(内存),但 close() 释放用于打开文件的操作系统资源(大多数系统上打开文件的数量有限)并确保数据确实被写入.

Garbage collection frees Java heap (memory) but close() frees OS resources used for open file (number of open files is limited on most system) and assures that the data is really written.

但是许多类,例如 FileInputStreamRandomAccessFile 都是用 finalize() 方法编写的,该方法确保如果垃圾回收中的实例,将首先调用 close().所以在很多情况下,垃圾回收确实会间接释放文件,而且程序员经常可能会懒于关闭资源,因为垃圾回收通常会为你清理它们.很遗憾.

But many classes such as FileInputStream and RandomAccessFile are written with a finalize() method which ensures that IF an instance in garbage collected, close() will be called first. So in many cases, garbage collection does indirectly free up files, and it is often possible for programmers to be lazy about closing resources, because garbage collection usually cleans them up for you. Unfortunately.

问题是您无法控制何时发生这种情况,而且它可能根本不会发生.因此,如果您打开了太多文件,操作系统可能会在垃圾收集器开始关闭它们之前给您一个错误.或者,如果您想移动或删除文件,请在读取文件后立即 - 移动或删除可能会失败,因为此时您仍然可以打开文件以供阅读.

The problem is that you can't control when this happens, and it may not happen at all. So if you have too many files open, the operating system may give you an error about that before the garbage collector gets around to closing them. Or if you want to move a file or delete it, immediately after reading it - the move or delete may fail, because at that moment you've still got the file open for reading.

这样的错误通常很难可靠地重现,因为它们取决于垃圾收集器的时间.所以你得到的东西通常可以正常工作,但有时会神秘地失败.调试起来很烦.出于这个原因,强烈建议您在完成后立即关闭()您可能正在使用的任何流/读取器/连接或其他可关闭资源.最好在 finally 块中,以确保即使在处理过程中发生一些其他错误也会发生.

Errors like this are often hard to reproduce reliably, because they depend on the timing of the garbage collector. So you get things which usually work fine, but sometimes fail mysteriously. Very annoying to debug. For this reason, it is stronly recommended to be sure to close() any stream/reader/connection or other closable resource you may be using, as soon as you are done with it. Preferably in a finally block, to ensure it happens even if some other error occurs in processing.

在 Java 7 中,添加了 AutoClosable 接口,了解更多信息这里.

And with Java 7, there is an addition of AutoClosable interface, read more about it here.

参考:http://www.coderanch.com/t/278165//java/InputStream-close-garbage-collection

相关文章