【发布时间】:2021-06-22 12:05:07
【问题描述】:
我正在尝试使用How to extract the file jre-9/lib/modules? 中描述的方法读取给定 Java 9+ 安装中可用的模块列表,给定它的 Java Home。
该解决方案有效,但分配用于读取 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);
}
}
}
}
【问题讨论】:
-
您使用的是哪个 Java 版本?
-
我正在使用 Jabba 来管理我的 Java 安装。我使用了以下版本:采用@1.14.0-2、采用@1.11.0-7、采用@1.8.0-242
-
好观察!这似乎是一个真正的 JDK 错误,由
ImageBufferCache中不小心使用线程局部变量引起的。 -
@apangin 刚来the same conclusion
标签: java memory-leaks jvm