我想知道当一个流关闭,如果它不是手动关闭。我的意思是,如果流的引用范围不再存在,流会被关闭吗?
考虑以下示例场景:
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负责这个吗?此外,我了解到,一旦进程结束,流将被关闭,系统将为其他进程释放为其持有的所有资源。我们如何检查流是否打开?是否有任何linux命令或Java选项来检查?
任何帮助都是感激的!
我不认为JVM规范对此做了任何保证。你真的应该finally
关闭这些资源。
当进程结束时,操作系统将释放与该进程相关的所有资源(包括内存、文件句柄和网络套接字)。
有操作系统工具来检查打开的文件和流,如lsof
。
在FileInputStream
的情况下,finalize()
方法将在流被垃圾收集时释放资源。
不是说你可以或应该依赖它。这正是FileInputStream
所做的。另一方面,SocketInputStream
覆盖finalize()
,显式地不做任何事情,依靠Socket
来关闭资源(Socket
没有finalize()
方法)。
如果您没有手动关闭它,那么在进程终止时将释放所有非托管资源,但是这不是推荐或最佳实践。你应该总是关闭你的流一旦你完成它。
管理流的一个更好的建议方法是像这样使用try和资源选项:
try (InputStream input = new FileInputStream(...);
Reader reader = new InputStreamReader(input, ...)) {
...
}
我没有关闭流。它会自动关闭吗对A类末端的引用范围?
不,它不会自动关闭。
一个很好的参考是:
使用Java SE 7实现更好的资源管理:超越语法糖
不能保证只要JVM在运行,资源就会被关闭,您建议的实现是相当危险的。
我的建议。将类A设置为Closeable,并使用Java的tryresourcecclose - statement。例子在这里。https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
离开try-block后,你有机会关闭你的资源。
流本身通常不知道它是否打开。但是,您自己的类A可以跟踪流是否关闭。
这是一个糟糕的编程实践,是程序员的错误。根据底层数据源的不同,它可能永远不会关闭,并且可能存在泄漏。在finally
块中,或者在Java 7或更高版本中使用try with resources,当你使用完任何资源时,你必须关闭它,以确保即使抛出异常也关闭它。
InputStream in;
OutputStream out;
try {
// Do your stuff with the streams
} finally {
if (in != null) {
in.close();
}
if (out != null) {
out.close();
}
}
在Java 7中,您可以在try语句中创建一个或多个"资源"。"资源"是实现java.lang.AutoCloseable接口的东西。此资源将自动关闭,try块结束。
你可以查看这个和Java文档获取更多信息
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构造中使用。