让我们假设您有一个 3 Gb 的 jar 文件,而您的应用程序只使用其中的一个小类。JVM 是将整个 jar 文件加载到内存中还是读取目录并仅加载它需要的部分?这种行为是否可控?
4 回答
JVM 在调用时仅从 Jar 加载所需的类。如果应用程序需要一个类,则将加载该类和所有其他依赖类。不确定,但我想这是类加载器从类路径中定位类并加载的责任。
Jar 文件是 zip 文件的一种形式。
如何处理这些在很大程度上取决于 JRE。
旧版本的 Sun JRE 用于内存映射整个文件。这将分配逻辑内存,但不一定会导致从磁盘加载任何数据。(32 位 Windows 通常不能分配 3 GB 的连续内存,尽管您可以在其他操作系统上做到这一点)。
我相信当前的行为是内存映射Windows下文件后面的中央目录。在其他操作系统下,它只是读取。这由#define
源中的 s 控制。
JDK7 可能会做其他事情。
类通常是延迟加载的。每次都会重读资源。java.util.ResourceBundle
缓存。
它完全取决于 JVM 和类加载器。JVM 规范指定类应该在其第一次活动使用时加载。类加载器可以比预期的需要更早地加载一些类。实际上,大多数类加载器会尽可能长时间地延迟加载。
默认类加载器仅在需要时加载它需要的内容。如果您的 CLASSPATH 中有一个 10MB 的 JAR,并且只需要一个 .class 文件,那么 JVM 只会在您的代码第一次尝试访问它时加载该类。.class 字节码进入 perm 空间。
从某种意义上说,它是“可控的”,您可以编写自己的类加载器,但这样做需要一些专业知识。