读完一篇JRT后如何释放所有资源?
我正在尝试使用如何提取文件 jre-9/lib/modules?.
该解决方案有效,但似乎分配给读取 Java 运行时映像内容的资源从未被释放,从而导致内存泄漏,例如可以通过 VisualVM 观察到:
如何修复以下再现中的内存泄漏?
package leak;
import java.net.URI;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collections;
import java.util.Map;
import java.util.stream.Stream;
public class JrtfsLeak {
public static void main(String[] args) throws Exception {
Path javaHome = Paths.get(args[0]);
for (int i = 0; i < 100000; ++i) {
modules(javaHome).close();
}
}
private static Stream<Path> modules(Path javaHome) throws Exception {
Map<String, String> env = Collections.singletonMap("java.home", javaHome.toString());
Path jrtfsJar = javaHome.resolve("lib").resolve("jrt-fs.jar");
try (URLClassLoader classloader = new URLClassLoader(new URL[] { jrtfsJar.toUri().toURL() })) {
try (FileSystem fs = FileSystems.newFileSystem(URI.create("jrt:/"), env, classloader)) {
Path modulesRoot = fs.getPath("modules");
return Files.list(modulesRoot);
}
}
}
}
回答
这是一个 JDK 错误JDK-8260621,已在 JDK 17 中修复。
这是由于在ImageBufferCache.