我在某处读到,没有必要自己关闭它,只需保留它,JVM 会帮助你做到这一点。这是真的吗?
假设我需要从文件中获取数据
Source.fromFile(fileName).getLines()
直接地,无需
val source = Source.fromFile(fileName)
val lines = source.getLines()
............
source.close()
第一种方式,我无法直接访问源代码并将其关闭。我的 JVM 工作了很长一段时间。我需要关闭一个文件(需要关闭未使用的资源)。
如果有人可以在这里留下一些链接或解释,那就太好了。
我在某处读到,没有必要自己关闭它,只需保留它,JVM 会帮助你做到这一点。这是真的吗?
这部分是正确的。
如果您打开一个文件,使用它,然后删除文件或流句柄(或任何您想调用的名称),并且 GC 找到它,那么 GC 会将文件句柄对象排队以进行最终确定。当最终确定发生时,文件处理程序的finalize()
方法会释放资源;即文件描述符。
然而,它是一个坏主意依靠 GC 来完成此操作。
- 如果文件句柄(仍然)可访问,则 GC 不会将其排队等待最终确定。
- You have no way of knowing when the GC is going to run next1.
- And when the GC runs, it won't necessarily collect all of the garbage2 (and hence queue all lost file handles).
- 排队等待终结的对象直到 GC 完成后才真正被终结。 (参见@Holger的评论)
将这四件事放在一起,在 GC 开始收集和关闭废弃的文件句柄之前,应用程序很容易耗尽文件描述符。如果发生这种情况,您可能会在打开文件、目录、套接字等的操作中遇到异常。
您可以运行以下示例(在 Linux / UNIX 上)来查看这种情况的发生:
import java.io.FileInputStream;
public class Test {
public static void main(String[] args) throws Exception {
for (int i = 0; i < 100000; i++) {
new FileInputStream("/etc/motd");
}
}
}
$ javac Test.java
$ java Test
Exception in thread "main" java.io.FileNotFoundException: /etc/motd (Too many open files)
at java.io.FileInputStream.open0(Native Method)
at java.io.FileInputStream.open(FileInputStream.java:195)
at java.io.FileInputStream.<init>(FileInputStream.java:138)
at java.io.FileInputStream.<init>(FileInputStream.java:93)
at Test.main(Test.java:6)
1 - A typical GC only runs when the heap (or part of the heap) reaches a given threshold of "fullness". If an application doesn't allocate many objects, it can take a long time for the threshold to be reached.
2 - Modern JVMs use generational garbage collectors which collect different parts of the heap at different rates.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)