Unreleased Resource: Files

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 是否已被初始化。

File 未释放文件权柄问题处理的更多相关文章

  1. Linux服务器文件删除空间未释放的问题

    一.问题起源 在Linux系统中,通过rm删除文件将会从文件系统的目录结构上解除链接(unlink),如果文件是被打开的(有一个进程正在使用),那么进程将仍然可以读取该文件磁盘空间也一直被占用 这样就 ...

  2. 如何恢复未释放租约的HDFS文件

    之前有文章介绍过HDFS租约带来的问题,导致spark应用无法正常读取文件,只能将异常文件找出并且删除后,任务才能继续执行. 但是删除文件实在是下下策,而且文件本身其实并未损坏,只是因为已经close ...

  3. linux服务器文件删除空间却未释放

    在Linux或者Unix系统中,通过rm或者文件管理器删除文件将会从文件系统的目录结构上解除链接(unlink),然而如果文件是被打开的(有一个进程正在使用),那么进程将仍然可以读取该文件,磁盘空间也 ...

  4. 【Linux命令】删除大文件后磁盘空间未释放问题

    前言 工作中经常遇到Linux系统磁盘空间不足,但是删除后较大的日志文件后,发现磁盘空间仍没有被释放,有点摸不着头脑,今天博主带大家解决这个问题. 思路 1.工作发现磁盘空间不足: 2.找到占用磁盘空 ...

  5. linux删除文件未释放空间问题处理

    linux删除文件未释放空间问题处理 或者 /根分区满了 (我的根分区是/dev/sda1,/dev/sda1满了) http://blog.csdn.net/donghustone/article/ ...

  6. LINUX文件删除,但磁盘空间未释放

    最近在进行系统压测,由于服务器节点太多,便写了个简单的脚本,在执行过程中发现,日志文件删除后,磁盘空间只释放了一小部分,任有大部分磁盘空间未释放. 使用lsof | grep delete命令,发现已 ...

  7. Linux文件删除空间未释放

    当系统空间使用量过大需要清理空间或者清理某个文件时,有时会出现执行了删除命令之后磁盘空间并没有释放,很多人首次遇到该情况时会比较困惑,在考虑是不是像windows系统的回收站一样,删除只是逻辑删除到回 ...

  8. mysql优化, 删除数据后物理空间未释放(转载)

    mysql优化, 删除数据后物理空间未释放(转载) OPTIMIZE TABLE 当您的库中删除了大量的数据后,您可能会发现数据文件尺寸并没有减小.这是因为删除操作后在数据文件中留下碎片所致.OPTI ...

  9. NSIS:静默释放文件并运行 制作绿色单文件软件

    原文 NSIS:静默释放文件并运行 制作绿色单文件软件 现在所谓的绿色单文件软件,大多与以下代码原理相似:把软件运行需要的文件封装为一个EXE文件,双击时释放到某个目录(大多是TEMP)并运行主程序文 ...

  10. 关于mysql 删除数据后物理空间未释放(转载)

    转自 关于mysql 删除数据后物理空间未释放(转载) - NETDATA - 博客园http://www.cnblogs.com/shawnloong/archive/2013/02/07/2908 ...

随机推荐

  1. Docker之基本原理介绍

    Docker 环境搭建请移步:https://i.cnblogs.com/posts/edit;postId=14090026 First:docker能做什么? 传统的环境部署: 1.环境和项目分开 ...

  2. 2020第十一届蓝桥杯大赛软件类国赛题目 C/C++ B 组

    试题 A: 美丽的 2 本题总分:5 分 问题描述:在公元 1 年到公元 2020 年(包含)中,有多少个年份的数位中包含数字 2? #include <stdio.h> #include ...

  3. SaaS、PaaS、IaaS的区别

    我们从SaaS.PaaS.IaaS的定义.工业应用以及具体案例几方面来介绍他们之间的区别 一.定义层面的区别 SaaS.PaaS.IaaS简单的说都属于云计算服务,也就是云计算+服务. 我们对于云计算 ...

  4. 类和动态内存分配的课后习题(C++ prime plus)

    第一题 1. 对于下面的类声明: class Cow { char name[20]; char *hobby; double weight; public: Cow(); Cow(const cha ...

  5. C#——》发布ASP.NET Core项目到Windows IIS服务器中环境部署

    服务器:Windows Server2012 R2 IIS:8 .net Core版本:1.1.2 一,在VS中点击项目-->依赖项-->SDK下可以查看当前项目.Net core是哪个版 ...

  6. Java中double保留2位小数(精度丢失)的两种方式

    Java中double保留2位小数(精度丢失)的两种方式 在我们日常开发中,使用double数据类型进行计算,偶尔会出现精度丢失的情况,例如实际结果是0.75,就可能出现0.7500000000000 ...

  7. 学习JavaScript第一周

    三种输出方式,console.log.element.write.alert(): 简单数据类型:数值型.字符串型.布尔类型.undefined.null 复杂数据类型:对象 数据类型的转换:字符串转 ...

  8. java流程控制;

    一.基础阶段: 1.用户交互Scanner Scanner对象: 之前我们学的基本语法中我们并没有实现程序和人的交互,但是Java给我们提供了这样一个工具类,我们可以获取用户的输入. java.uti ...

  9. tortoiseGit配置和git常用命令

    tortoiseGit配置:https://blog.csdn.net/hjwdz2015/article/details/90487554 常用命令 一.git config --global us ...

  10. Ubuntu解决无法远程连接

    检查SSH是否安装 ssh localhost 如果没有安装,通过APT的命令安装 sudo apt install openssh-server 无法连接Ubuntu中的root用户 其他用户可以连 ...