我想知道如果一个流没有手动关闭,它什么时候关闭。我的意思是,如果它的引用范围不再是,那么流将被关闭吗?
请考虑以下示例场景。
Class A{
InputStream in;
OutputStream out;
A(){
// Initialize and create the streams.
}
...
}
Class B{
public void myMethod(){
A a = new A();
System.out.println("End of my method.")
}
...
}
在这里,一旦我完成了流,我将退出myMethod()
,但程序反过来进程,不会终止并继续进行其他操作。
我没有关闭溪流。一旦A类参考范围结束,它会自动关闭吗? (即myMethod()
何时结束)? GC会照顾到吗?此外,我读到,一旦进程结束,流将被关闭,系统将释放为其他进程保留的所有资源。我们如何检查流是否开放?是否有来自Java的任何linux命令或选项来检查?
感谢任何帮助!
答案 0 :(得分:11)
我不认为JVM规范对此有任何保证。你真的应该finally
关闭这些资源。
当进程结束时,操作系统将释放与其关联的所有资源(包括内存,文件句柄和网络套接字)。
有操作系统可以检查打开的文件和流,例如lsof
。
答案 1 :(得分:4)
如果您没有手动压缩它,那么当进程终止时,将释放所有非托管资源,但这不是推荐的或最佳做法。完成后,您应该始终关闭流。
管理流的更好和建议的方法是使用try with resource选项,如下所示:
try (InputStream input = new FileInputStream(...);
Reader reader = new InputStreamReader(input, ...)) {
...
}
我没有关闭溪流。它会自动关闭吗? A类的引用范围结束了吗?
不,它不会自动关闭。
以下是一个很好的参考:
Better Resource Management with Java SE 7: Beyond Syntactic Sugar
答案 2 :(得分:3)
在FileInputStream
的情况下,有一个finalize()
方法,当流被垃圾收集时,它将释放资源。
不是说你可以或应该依赖它。这正是FileInputStream
的作用。另一方面,SocketInputStream
会覆盖finalize()
以明确不执行任何操作,依靠Socket
关闭资源(而Socket
没有finalize()
方法)
答案 3 :(得分:1)
只要JVM正在运行,就无法保证资源将被关闭。您建议的实现非常危险。
我会建议什么。 使类A成为Closeable并使用Java的tryResourceClose-Statement。 这个例子在这里。 https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
离开try-block后,您将有机会关闭资源。
流本身通常不知道它是否打开。 但是,您自己的A类可以跟踪流是否已关闭。
答案 4 :(得分:0)
这是一个糟糕的编程习惯,程序员的错误。根据底层数据源,它可能永远不会关闭,您可能会有泄漏。当你完成它,在finally
块中,或者使用Java 7或更高版本的资源尝试时,你必须关闭任何资源,以确保即使抛出异常也关闭它。
InputStream in;
OutputStream out;
try {
// Do your stuff with the streams
} finally {
if (in != null) {
in.close();
}
if (out != null) {
out.close();
}
}
答案 5 :(得分:0)
使用Java 7,您可以在try语句中创建一个或多个“资源”。 “资源”是实现java.lang.AutoCloseable接口的东西。该资源将自动关闭并且尝试块结束。
private static void printFileJava7() throws IOException {
try(FileInputStream input = new FileInputStream("file.txt")) {
int data = input.read();
while(data != -1){
System.out.print((char) data);
data = input.read();
}
}
}
当try块完成时,FileInputStream将自动关闭。这是可能的,因为FileInputStream实现了Java接口java.lang.AutoCloseable。实现此接口的所有类都可以在try-with-resources构造中使用。
答案 6 :(得分:0)
说在过程结束时将清除资源是不正确的。开放资源是第一手的系统调用。该进程主要是Java进程,而不是OS进程,取决于底层OS。因此,通常来说,由于JVM无法保证操作系统的系统调用所必需的此类操作,因此,如果您不关闭流,则资源请求的状态不确定,因此资源是确定的,因为Java无法保证关于它,尝试资源恰好是此的简写。但是50%的人不会关闭流。