con*_*fin 6 java memory heap native
在Java 8中,close()方法InflaterInputStream如下所示
public void close() throws IOException {
if (!closed) {
if (usesDefaultInflater)
inf.end();
in.close();
closed = true;
}
}
Run Code Online (Sandbox Code Playgroud)
usesDefaultInflater是一个布尔值,仅true当使用以下构造函数时
public InflaterInputStream(InputStream in) {
this(in, new Inflater());
usesDefaultInflater = true;
}
Run Code Online (Sandbox Code Playgroud)
诸如此类的其他任何构造函数都会导致此布尔值设置为false
new InflaterInputStream(decryptInputStream, new Inflater(), 4096);
Run Code Online (Sandbox Code Playgroud)
因此,除非使用默认的构造函数,否则end()不会在上调用该方法Inflater,这意味着不必要的本机内存消耗,直到终结器线程可能在关闭了很长一段时间后才在Finalizer线程finalize上调用该方法。请参阅下面的实现。InflaterInflaterInputStreamInflater
/**
* 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();
}
Run Code Online (Sandbox Code Playgroud)
为了解决这个问题,您需要重写类似的close方法,InflaterInputStream这样
new InflaterInputStream(decryptInputStream, new Inflater(), 4096) {
@Override
public void close() throws IOException {
try {
super.close();
} finally {
inf.end();
}
}
}
Run Code Online (Sandbox Code Playgroud)
这是很容易错过,它似乎对我来说,它可能是明智调用end()默认情况下,允许用户通过提供一个构造函数,你可以指定替代该行为false,或者至少是一个构造函数,使用默认Inflater但也允许您设置缓冲区大小。
无论如何,我猜测它是按原样设计的,这是有逻辑的,而我只是未能理解它。希望有人能启发我...
这也适用于DeflaterInputStream,DeflaterOutputStream和InflaterOutputStream在其他之中。
Java 运行时库中有许多方法采用例如 an OutputStream(例如Files.copy())。除非这些方法明确声明该方法将关闭该流,否则该流将不会被关闭。关闭流是流“所有者”(例如方法的调用者)的责任。
类似地,InflaterInputStream它的构造函数都没有Inflater声明它们将end(),Inflater这意味着它们不会。当需要时,由调用者决定结束它。
Inflater当使用为您创建 的构造函数时, 成为该内部InflaterInputStream的“所有者” ,因此结束的责任是。 InflaterInflaterInputStreamInflater
资源管理的一般准则是,除非另有说明,分配资源的人负责释放(关闭、结束……)资源。
Inflater是一种资源,因此适用正常的资源管理规则。
| 归档时间: |
|
| 查看次数: |
51 次 |
| 最近记录: |