有多个类的罐子的内存消耗量?

时间:2013-09-06 08:37:05

标签: java memory memory-management jar classloader

方案

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

问题

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

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

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

背景

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

因此,存在磁盘空间方面和项目组织的代码/可恢复性方面。项目组织的第三个方面是我想要回答的运行时/类加载器方面。虽然应用程序很少耗尽磁盘空间,但内存不足是一个现实的情况,具体取决于环境。

2 个答案:

答案 0 :(得分:3)

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

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

此内存消耗与jar文件大小本身无关,而与内部类的数量无关。

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

答案 1 :(得分:1)

由于需要打开和处理的大小的罐子,内存消耗会更高。但至于类 - 不,通常类是“按需”加载的,除了从引导类路径中可能少数。但它确实依赖于类加载器实现。

至于清理未使用的类......是的,JVM以类似于普通的基于可达性的垃圾收集方式执行此操作。但是要注意类加载器泄漏 - 有时类对象仍然以一种非常明显的方式保持可达,这在容器中表现得特别讨厌,并且容易导致可怕的OutOfMemoryException: PermGen space异常。