2

设想

让我们假设一个具有依赖关系的应用程序。依赖项以 jar 文件的形式出现。依赖 jar 文件包含许多类。该应用程序仅使用依赖项 jar 中的一个类。

问题

依赖 jar 中包含的未使用的类是否会导致更高的内存消耗,即使它们没有被应用程序(直接和间接)使用。

我想这是类加载器实现的问题,但是类加载器在这个问题上的行为真的不同吗?我认为对于默认的 JRE / JDK 类加载器以及常见容器和应用程序服务器的类加载器来说,回答这个问题就足够了。

类加载器是否加载整个 jar 文件?加载所需的类是否只是临时的,然后从内存中删除 jar 文件?还是所有类都加载了,甚至是未使用的类?

背景

当我组织我的项目时,我倾向于在许多小项目中拆分课程等。我这样做不是为了节省磁盘空间,因为磁盘空间相对便宜。我这样做是因为它增加了可重用性。即使小型项目的数量非常多,我也不太担心“依赖地狱”。我使用dependency-/build-tools 为我自动解决依赖关系。

所以有磁盘空间方面和项目组织的代码/可重用性方面。项目组织的第三个方面是我想回答的运行时/类加载器方面。虽然应用程序很少会用完磁盘空间,但内存不足是一种现实情况,具体取决于环境。

4

2 回答 2

3

简短的回答是YES。内存消耗更高。

类加载器不会加载整个 jar 文件。通过一个 ZipFile 对象,它只保留一个类列表和一个在 jar 文件中可以找到它们的偏移量。如果 jar 文件有很多类,则此列表更大,因此会消耗更多内存。

这种内存消耗与 jar 文件本身的大小无关,而与里面的类数有关。

除此之外,只有加载的类使用内存。

于 2013-09-06T08:49:49.100 回答
1

由于需要打开和处理的罐子的大小,内存消耗会更高。但至于类 - 不,一般来说,类是“按需”加载的,除了引导类路径中的少数类。不过,它确实取决于类加载器的实现。

As for cleanup of unused classes... yes, the JVM does that, in a manner similar to ordinary, reachability-based garbage collection. Be wary of classloader leaks though - sometimes the class object remains reachable in a not-at-all-obvious way, which manifests itself especially nasty in containers, and easily leads to te dreaded OutOfMemoryException: PermGen space exceptions.

于 2013-09-06T08:48:51.033 回答