在 Java 8 中,close()方法InflaterInputStream如下所示
public void close() throws IOException {
if (!closed) {
if (usesDefaultInflater)
inf.end();
in.close();
closed = true;
}
}
usesDefaultInflater是一个布尔值,仅true当使用下面的构造函数时
public InflaterInputStream(InputStream in) {
this(in, new Inflater());
usesDefaultInflater = true;
}
任何其他构造函数(例如下面的构造函数)都会导致此布尔值设置为 false
new InflaterInputStream(decryptInputStream, new Inflater(), 4096);
因此,除非您使用默认构造end()函数,否则不会在 上调用该方法,这意味着在 Finalizer 线程可能在关闭后很长时间内调用Inflater该方法之前会消耗不必要的本机内存。请参阅下面的实现。finalizeInflaterInflaterInputStreamInflater
/**
* Closes the decompressor and discards any unprocessed input.
* This method should be called when the decompressor is no longer
* being used, but will also be called automatically by the finalize()
* method. Once this method is called, the behavior of the Inflater
* object is undefined.
*/
public void end() {
synchronized (zsRef) {
long addr = zsRef.address();
zsRef.clear();
if (addr != 0) {
end(addr);
buf = null;
}
}
}
/**
* Closes the decompressor when garbage is collected.
*/
protected void finalize() {
end();
}
为了解决这个问题,你需要像这样重写close方法InflaterInputStream
new InflaterInputStream(decryptInputStream, new Inflater(), 4096) {
@Override
public void close() throws IOException {
try {
super.close();
} finally {
inf.end();
}
}
}
end()这很容易被忽略,在我看来,默认调用并允许用户通过提供一个您可以指定的构造函数来覆盖该行为可能是明智的false,或者至少是一个使用默认值Inflater但也允许您设置缓冲区大小。
无论如何,我猜它的设计方式有一些合乎逻辑的原因,而我只是没能理解它。希望有人能赐教。。。
这也适用于DeflaterInputStream、DeflaterOutputStream等InflaterOutputStream。
牧羊人nacy
弑天下
相关分类