这个问题可能有点难以找到答案。这是What is the reason that Policy.getPolicy() is considered as it will retain a static reference to the context and can cause memory leak系列中的一个问题。您可以阅读它,以便了解更多背景信息。
从org.apache.cxf.common.logging.JDKBugHacks
和org.apache.catalina.core.JreMemoryLeakPreventionListener
获取源代码。
有一段代码。在这里。
URL url = new URL("jar:file://dummy.jar!/");
URLConnection uConn = new URLConnection(url) {
@Override
public void connect() throws IOException{
// NOOP
}
};
uConn.setDefaultUseCaches(false);
评论说
/*
* Several components end up opening JarURLConnections without
* first disabling caching. This effectively locks the file.
* Whilst more noticeable and harder to ignore on Windows, it
* affects all operating systems.
*
* Those libraries/components known to trigger this issue
* include:
* - log4j versions 1.2.15 and earlier
* - javax.xml.bind.JAXBContext.newInstance()
*/
但我很难理解。为什么他们急切地打电话给setDefaultUseCaches(false)
以及为什么在Windows上,默认缓存是真的有害?我在java.net.JarURLConnection
找不到任何线索。
答案 0 :(得分:4)
我自己找到答案。如果你认为我错了,任何人都可以纠正我。
在sun.net.www.protocol.jar.JarURLConnection
。我假设这是java.net.JarURLConnection
的默认实现。下面有一段代码。
如果cache设置为true,则它不会关闭JarFile的连接。这意味着它被锁定了。
class JarURLInputStream extends java.io.FilterInputStream {
JarURLInputStream (InputStream src) {
super (src);
}
public void close () throws IOException {
try {
super.close();
} finally {
if (!getUseCaches()) {
jarFile.close(); //will not close
}
}
}
}
public void connect() throws IOException {
if (!connected) {
/* the factory call will do the security checks */
jarFile = factory.get(getJarFileURL(), getUseCaches());
/* we also ask the factory the permission that was required
* to get the jarFile, and set it as our permission.
*/
if (getUseCaches()) {
jarFileURLConnection = factory.getConnection(jarFile);
}
if ((entryName != null)) {
jarEntry = (JarEntry)jarFile.getEntry(entryName);
if (jarEntry == null) {
try {
if (!getUseCaches()) {
jarFile.close(); //will not close
}
} catch (Exception e) {
}
throw new FileNotFoundException("JAR entry " + entryName +
" not found in " +
jarFile.getName());
}
}
connected = true;
}
}