ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

File 未释放文件权柄问题处理

2021-05-13 12:36:10  阅读:502  来源: 互联网

标签:文件 释放 fName 句柄 zf ZipFile 权柄 File null


Unreleased Resource: Files (2 issues)

Abstract

程序可能无法释放某个文件句柄。

Explanation

程序可能无法成功释放某一个文件句柄。 资源泄露至少有两种常见的原因: - 错误状况及其他异常情况。 - 未明确程序的哪一部份负责释放资源。 大部分 Unreleased Resource 问题只会导致一般的软件可靠性问 题,但如果攻击者能够故意触发资源泄漏,该攻击者就有可能通过耗尽资源池的方式发起 denial of service 攻 击。 例 1:下面的方法绝不会关闭它所打开的文件句柄。 ZipFile 中的 finalize() 方法最终会调用 close(),但是不能确定何时会调用 finalize() 方法。 在繁忙的环境中,这会导致 JVM 用尽它所有的文 件句柄。
public void printZipContents(String fName) throws ZipException, IOException, SecurityException,
    IllegalStateException, NoSuchElementException{
  ZipFile zf = new ZipFile(fName);
  Enumeration<ZipEntry> e = zf.entries();
  while (e.hasMoreElements()) {
    printFileInfo(e.nextElement());
  }
}

 

例 2:正常情况下,以下修复代码会在输出所有 zip 文件条目之后正常关闭文件句柄。 如果迭代这些条目时 出现异常,则不会关闭 zip 文件句柄。 如果这种情况经常出现,JVM 就可能耗尽所有可用的文件句柄。
public void printZipContents(String fName) throws ZipException, IOException, SecurityException,
  IllegalStateException, NoSuchElementException{
    ZipFile zf = new ZipFile(fName);
    Enumeration<ZipEntry> e = zf.entries();
    while (e.hasMoreElements()) {
      printFileInfo(e.nextElement());
    }
}

 

Recommendation

1.绝不要依赖 finalize() 回收资源。 为了使对象的 Finalize() 方法能被调用,垃圾收集器必须确认对 象符合垃圾回收的条件。 但是垃圾收集器只有在 JVM 内存过小时才会使用。因此,无法保证何时能够调用该 对象的 finalize() 方法。 垃圾收集器最终运行时,可能出现这样的情况,即在短时间内回收大量的资源, 这种情况会导致“突发”性能,并降低总体系统通过量。 随着系统负载的增加,这种影响会越来越明显。 最 后,如果某一资源回收操作被挂起(例如该操作需要通过网络进行通信),那么执行 finalize() 方法的线 程也将被挂起。 2. 在 finally 代码段中释放资源。 例 2 中的代码可按以下方式改写:
public void printZipContents(String fName) throws ZipException, IOException, SecurityException,
  IllegalStateException, NoSuchElementException{
    ZipFile zf;
    try {
      zf = new ZipFile(fName);
      Enumeration<ZipEntry> 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);     }   } }

 

以上方案使用了一个助手函数,用以记录在尝试关闭文件时可能产生的异常。 该助手函数大约会在需要关闭 文件时重新使用。 同样,printZipContents 方法不会将 zf 对象初始化为 null。 而是进行检查,以确保 调用 safeClose() 之前,zf 不是 null。 如果没有检查 null,Java 编译器会报告 zf 可能没有进行初始 化。 编译器做出这一判断源于 Java 可以检测未初始化的变量。 如果用一种更加复杂的方法将 zf 初始化为 null,那么 Java 编译器就无法检测 zf 是否已被初始化。

标签:文件,释放,fName,句柄,zf,ZipFile,权柄,File,null
来源: https://www.cnblogs.com/xiaro115/p/14764035.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有