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

时间:2011-12-21 16:39:32

标签: java performance memory jar

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

但是对于包含许多可能使用或不使用的库的大型长寿程序而言。

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

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

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

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

3 个答案:

答案 0 :(得分:11)

这不是问题,你不应该担心。类加载器足够智能,可以加载所需的类,并且通常按需加载类(即通常不会加载一堆不会被使用的代码)。这与您的应用程序的运行时间有多长或无关。

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

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

我认为smooth reggae's答案适用于类加载主题的其他一些细节。

答案 1 :(得分:7)

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

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

对大量文件进行文件访问将是低效的。 JDK在jars之前使用zip作为系统类。

(如果存在静态初始化程序,则静态初始化之前可能会发生类加载 - 请参阅三参数Class.forName。)

答案 2 :(得分:3)

JVM规范中的

How classes are foundthe chapter on loading, linking and initializing是有用的参考。

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