由IO流关闭引发的关于垃圾回收机制及finalize()的理解

来源:互联网 发布:淘宝商品不含区间价格 编辑:程序博客网 时间:2024/05/18 05:55

    前段时间行方服务器由于IO流未正确关闭而多次宕机,为此特意开会强调了IO流关闭的问题,现将比较标准的IO流关闭代码整理出来:

OutputStream os = null;try {    //假设从已有响应对象response中获取了输出流对象    os = response.getOutputStream();    System.out.println("执行一些输出流操作");}catch(Exception e) {    System.out.println("捕获异常");}finally {    if(os != null) {        try {            os.close();        }catch(Exception e) {            os = null; //[1]        }    }}

    以上就是单一流关闭大致步骤,关于IO流,其实还有几点:1. 习惯上,先开的流后关闭;2. 如存在装饰流,只关闭装饰流即可,内层被装饰的流会自动关闭;3. 一个finally里中关闭多个流,需要分别try-catch,防止异常影响后续代码不执行。

可能有朋友会对【注1】的

os = null;

有疑问,这就引出了java的垃圾回收机制。

    java垃圾回收的大原则是:JVM会在存储空间即将耗尽前,清理不再使用的对象,以释放空间。
    此处,如果os关闭出现异常,则将os的引用置空,那么堆中流对象将被闲置,如果出现存储空间即将耗尽的情况,那么该对象将会被回收以释放空间,这就是此行代码的解释。

    提到垃圾回收,我一下就联想到finalize()方法(或许是学习时区分final,finally,finalize()三者区别的面试题印象比较深)。在阅读5.5节之前,对finalize()理解停留在:Object类的方法,用于垃圾回收,没了。读后,对这部分加深了理解。
    关于finalize(), 大原则是:能不用就不用,用也不用于清理操作。书中例子很有启发性:作为“终结条件”的验证。所谓终结条件,即对象将被清理时,应当处于某种状态,在执行finalize()时,校验这种状态,如果这个状态不满足预期,那么可能就是程序有缺陷。这个思路确实很巧妙,finalize()可能用的不多,但是这种思想如果外延到普通的程序状态验证,某种程度上确实会帮助我们定位问题。
    同样的,这部分学习的还不够深入,后续再做补充。