解决高风险代码:Unreleased Resource: Streams

Abstract
程序可能无法成功释放某一项系统资源。

Explanation
程序可能无法成功释放某一项系统资源。 资源泄露至少有两种常见的原因: - 错误状况及其他异常情况。
- 未明确程序的哪一部份负责释放资源。 大部分 Unreleased Resource 问题只会导致常规软件可靠性问题,
但如果攻击者能够故意触发资源泄漏,该攻击者就有可能通过耗尽资源池的方式发起 Denial of Service 攻
击。 示例: 下面的方法绝不会关闭它所打开的文件句柄。 FileInputStream 中的 finalize() 方法最终
会调用 close(),但是不能确定何时会调用 finalize() 方法。在繁忙的环境中,这会导致 JVM 用尽它所
有的文件句柄。
private void processFile(String fName) throws FileNotFoundException,
IOException {
FileInputStream fis = new FileInputStream(fName);
int sz;
byte[] byteArray = new byte[BLOCK_SIZE];
while ((sz = fis.read(byteArray)) != -1) {
processBytes(byteArray, sz);
}
}
Recommendation

  1. 请不要依赖 finalize() 回收资源。为了使对象的 finalize() 方法能被调用,垃圾收集器必须确认对
    象符合垃圾回收的条件。但是垃圾收集器只有在 JVM 内存过小时才会使用。因此,无法保证何时能够调用该
    对象的 finalize() 方法。垃圾收集器最终运行时,可能出现这样的情况,即在短时间内回收大量的资源,
    这种情况会导致“突发”性能,并降低总体系统通过量。随着系统负载的增加,这种影响会越来越明显。 最
    后, 如果某一资源回收操作被挂起(例如该操作需要通过网络访问数据库),那么执行 finalize() 方法的
    线程也将被挂起。 2. 在 finally 代码段中释放资源。示例中的代码可按以下方式改写:
    public void processFile(String fName) throws FileNotFoundException,
    IOException {
    FileInputStream fis;
    try {
    fis = new FileInputStream(fName);
    int sz;
    byte[] byteArray = new byte[BLOCK_SIZE];
    while ((sz = fis.read(byteArray)) != -1) {
    processBytes(byteArray, sz);
    }
    }
    finally {
    if (fis != null) {
    safeClose(fis);
    }
    }
    }
    public static void safeClose(FileInputStream fis) {
    if (fis != null) {
    try {
    fis.close();
    } catch (IOException e) {
    log(e);
    }
    }
    }
    以上方案使用了一个助手函数,用以记录在尝试关闭流时可能发生的异常。该助手函数大约会在需要关闭流
    时重新使用。 此外, processFile 方法不会将 fis 对象初始化为 null,而是进行检查,以确保在调用
    safeClose() 之前fis 不为 null。如果没有进行 null 检查, Java 编译器就会报告 fis 可能没有进行初
    始化。编译器做出这一判断源于 Java 可以检测未初始化的变量。如果用一种更加复杂的方法将 fis 初始化
    为 null,那么编译器就无法检测 fis 未经初始化便使用的情况。

示例1
未处理前产生的问题
在这里插入图片描述
解决后如下
在这里插入图片描述
示例2
未处理前产生的问题
在这里插入图片描述
解决后如下
在这里插入图片描述
在这里插入图片描述

  • 18
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

子非我鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值