繁体   English   中英

JVM如何在JARs的列表中找到一个class的文件?

[英]How does JVM find a class file among a list of JARs?

根据我的理解,Java 启动器通过搜索类路径找到一个 class 文件,其中可以包含 JARs 的列表(参考https://docs.oracle.com/javase/8/docs/technotes/tools8.88/finding1classes86/4 )。 我的问题是,如果要查找 JARs 和 class 的列表,Java 是否会逐一搜索每个 JAR,或者如果没有,它如何找到正确的 class 文件? 它是否缓存了进程中的任何内容,例如来自 JARs 的目录结构? 如果 JARs 的列表很长,是否会导致性能问题或 memory?

我确实看过这篇文章: How does Java efficiently search jar files for classes? ,但没有提及默认行为或可以进行哪些优化。

谢谢你。

这是一个粗略的答案,对此感到抱歉。 但这可能总比没有好,所以我们在这里 go。

因此,当您引用 JVM 尚未加载的某些 class 时,JVM 确实开始查看 class 路径,逐一迭代其项目。 如果您指的是 abC,则 JVM 会查找条目 a/b/C.class。

类路径可以由许多不同的东西组成。 它实际上是由类加载器抽象出来的,它可以做任何事情,例如通过 Inte.net 或 select 从数据库下载类文件。 但通常它只查看 JAR 个文件(或也是有效类路径条目的目录)。

JAR 文件是 ZIP 文件,而 ZIP 文件有 header,这允许相对快速的查找。 它不是超级性能,所以如果你的类路径很大,你可能会通过将它组合到一个 uberjar 中来获得一些性能提升。 如果您将 jars 替换为提取的文件夹,您也可能会获得一些性能提升。 但不要把它当作建议,很可能提升可以忽略不计。

在 ClassLoader 找到 .class 文件后,它读取其内容并将其字节“发送”到 JVM。它还可以在将这些字节“发送”到 JVM 之前更改这些字节。因此,您可能会使用这些神奇的类加载器实现一些神奇的事情。 但是普通的类加载器不会那样做。

在 JVM 得到这些字节后,它会解析、验证、编译,最后这个 class 会以某种非常适合执行的形式加载到 JVM 地址空间中。 从现在开始,这个 class 将被“立即”查找。

我认为如果程序中没有引用 JVM 也可以卸载未使用的 class,所以我想这个过程可以对同一个 class 重复。但这不是你应该担心的事情。

要记住的另一件事是类路径是 Java 8 东西。 它仍然可以在现代 Java 中使用,但由于 Java 出现了 9 个模块路径,可以与 class 路径并行使用(或作为替代)。 据我了解,当涉及到我上面描述的低级细节时,它们是相似的,但我想值得提醒一下。 我认为大多数程序还没有包含模块,但我没有统计数据。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM