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

2022-09-03 01:45:03

在我看来,(如果我错了,请纠正我)一个类被缓存,因此只有在第一次引用类时才需要搜索类路径。它只会在调用静态初始值设定项时发生,这在程序的生命周期中只有一次。(或者更具体地说,类装入器)

但是,对于一个大型的长寿命程序,其中包含许多可能使用或可能不使用的库。

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

引用目录是更好的选择吗?还是Jar文件已经解压缩到临时位置开始?

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

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


答案 1

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

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

至于更快的问题,我想各种方法之间可能存在一些差异,但是如果有,您可以通过实验来轻松测试自己。这种情况可能是特定于应用程序的,因为每个应用程序加载的代码是不同的。

我认为流畅的雷鬼的答案对于类加载主题的一些额外细节是很好的。


答案 2

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

查找每个类应该是恒定的时间。但是,那里有一些O(n)算法。因此,对于整个应用程序,O(n^2)用于类加载(尽管常量非常小,并且很可能由线性时间运算主导)。

对加载的文件执行文件访问将效率低下。JDK 在 jar 之前对系统类使用 zip。

(类加载可能发生在静态初始化之前的某个时间,此时静态初始化器将运行(如果存在) - 请参阅三参数。Class.forName


推荐