在org.apache.catalina.core.JreMemoryLeakPreventionListener中急切调用URLConnection的setDefaultUseCaches(false)的原因是什么
这个问题可能有点难以找到答案。 这是一个系列中的问题。 考虑Policy.getPolicy()的原因是什么,因为它将保留对上下文的静态引用并可能导致内存泄漏 。 你可以阅读它,这样你就可以了解更多背景知识。
从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
找不到任何线索。
我自己找到答案。 如果你认为我错了,任何人都可以纠正我。 在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; } }