Skip to content

Commit

Permalink
Create 资源未释放:文件
Browse files Browse the repository at this point in the history
  • Loading branch information
wooyunwang authored Dec 3, 2019
1 parent 2f9dad8 commit f22296d
Showing 1 changed file with 32 additions and 0 deletions.
32 changes: 32 additions & 0 deletions 资源未释放:文件
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
1. 请不要依赖 finalize() 回收资源。为了使对象的 finalize() 方法能被调用,垃圾收集器必须确认对象符合垃圾回收的条件。但是垃圾收集器只有在 JVM 内存过小时才会使用。因此,无法保证何时能够调用该对象的 finalize() 方法。垃圾收集器最终运行时,可能出现这样的情况,即在短时间内回收大量的资源,这种情况会导致“突发”性能,并降低总体系统通过量。随着系统负载的增加,这种影响会越来越明显。
最后,如果某一资源回收操作被挂起(例如该操作需要通过网络进行通信),那么执行 finalize() 方法的线程也将被挂起。
2. 在 finally 代码段中释放资源。例 2 中的代码可按以下方式改写:
<pre>
public void printZipContents(String fName)
throws ZipException, IOException, SecurityException, IllegalStateException, NoSuchElementException
{
ZipFile zf;
try {
zf = new ZipFile(fName);
Enumeration e = zf.entries();
...
}
finally {
if (zf != null) {
safeClose(zf);
}
}
}

public static void safeClose(ZipFile zf) {
if (zf != null) {
try {
zf.close();
} catch (IOException e) {
log(e);
}
}
}
</pre>
以上方案使用了一个助手函数,用以记录在尝试关闭文件时可能产生的异常。该助手函数大约会在需要关闭文件时重新使用。
同样, printZipContents 方法不会将 zf 对象初始化为 null。而是进行检查,以确保调用 safeClose() 之前, zf 不是 null。如果没有检查 null,Java 编译器会报告 zf 可能没有进行初始化。编译器做出这一判断源于 Java 可以检测未初始化的变量。如果用一种更加复杂的方法将 zf 初始化为 null,那么编译器就无法检测 zf 未经初始化便使用的情况。

0 comments on commit f22296d

Please sign in to comment.