包含多个(甚至可能是未使用的)jar文件的大型类路径是否效率低下



我看到它的方式,(纠正我,如果我错了)一个类被缓存,所以需要搜索类路径是必要的,只有第一次类被引用。它只会在调用静态初始化器时发生,在程序的生命周期中只有一次。(或者更具体地说,是类装入器)

但是对于一个大型的、长寿命的程序,它包含了许多可能使用也可能不使用的库,

Jar文件是否被加载到内存中,由于大多数类从未被使用而导致不必要的使用?它会留在记忆中吗?

引用目录是更好的选择吗?或者Jar文件已经解压缩到一个临时位置?

使用目录方法比使用Jar文件方法更快吗?

将所有Jar文件提取到单个目录中以减少类路径中的位置数量是否合理?什么时候这是个好主意?

这不是问题,你不应该担心。类加载器足够聪明,可以加载它需要的类,并且经常按需加载类(也就是说,它通常不会加载一堆不会被使用的代码)。这与应用程序的大小或运行时间无关。

在大量JAR的情况下,我更关心JAR Hell。

至于更快的问题,我想不同的方法之间可能会有一些区别,但如果有的话,你可以很容易地通过实验来测试自己。这种情况可能是特定于应用程序的,因为每个应用程序加载的代码是不同的。

我认为smooth reggae的回答对于类加载主题的一些额外细节是很好的。

jar文件中心目录(放在zip的末尾)将被解析并加载到内存中。该目录是平面的,因此需要加载所有内容。当启动一个简单的Java进程时,延迟的一个重要部分是打开rt.jar,这是一个巨大的延迟。是的,这就是启动时间和内存开销

查找每个类应该是常数时间。然而,这里有一些O(n)算法。因此,对于整个应用程序来说,类加载的时间为O(n^2)(尽管该常数相当小,并且很可能由线性时间操作主导)。

在加载文件时进行文件访问将是低效的。在jar之前,JDK使用zip来存放系统类。

(类加载可能发生在静态初始化之前的一段时间,当静态初始化器存在时将运行-参见三参数Class.forName。)

如何找到类以及JVM规范中关于加载、链接和初始化的章节是有用的参考。

从个人经验来看,我可以证明javac的类路径越长,编译所花费的时间就越多;当您的类路径包含编译不需要的jar时,这尤其是个问题。对于一个简单的测试,尝试在没有-cp的情况下编译规范的HelloWorld.java,将几个JAR文件添加到-cp,然后将几个JAR文件添加到-cp;编译所花费的时间随着-cp列表中jar数量的增加而增加。

最新更新