西安网站建设网站推广,老薛主机 wordpress,广西建设网官方网桂建云,莆田企业免费建站Overview java 中的函数 getResponseBytes() 有时无法成功释放由 getInputStream() 函数分配的系统资源。
Details
程序可能无法成功释放某一项系统资源。 在这种情况下#xff0c;在某些程序路径上#xff0c;所分配的资源未释放。 资源泄露至少有两种常见的原因#xf…Overview java 中的函数 getResponseBytes() 有时无法成功释放由 getInputStream() 函数分配的系统资源。
Details
程序可能无法成功释放某一项系统资源。 在这种情况下在某些程序路径上所分配的资源未释放。 资源泄露至少有两种常见的原因 错误状况及其他异常情况。 未明确程序的哪一部份负责释放资源。
大部分 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);
}
}
Recommendations
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 未经初始化便使用的情况。