当一个用Java编写的程序运行时,它的所有类会全部加载到主存中吗?如果是这样,那不是浪费RAM吗?
2 回答
不,没关系,因为虚拟地址空间和虚拟内存。阅读这些:
http://en.wikipedia.org/wiki/Virtual_memory
http://en.wikipedia.org/wiki/Virtual_address_space
虚拟内存意味着您可以将大量内容加载到内存中,而未使用的部分将保存到磁盘并从物理 RAM 中移出。
虚拟地址空间意味着每个进程(进程的一个示例是您的 Java 程序)都有自己的地址空间,因此它不会“窃取”其他进程的地址。
仅加载在特定执行期间引用的类。大多数大型 Java 程序将经常在许多未加载的类的情况下运行,因为这些类服务于该特定进程未执行的各种场景。
标准库中的类的处理方式与应用程序类相同。例如,如果您的应用程序不引用 AWT,则不会加载 AWT 包中的类。
Java 语言规范包含明确排除类的急切初始化的措辞。
类或接口类型 T 将在以下任何一项第一次出现之前立即初始化:
- T 是一个类,并创建了一个 T 的实例。
- T 是一个类,并且调用了 T 声明的静态方法。
- 分配了一个由 T 声明的静态字段。
- 使用了由 T 声明的静态字段,并且该字段不是常量变量(第 4.12.4 节)。
- T 是一个顶级类,一个断言语句(第 14.10 节)是词法嵌套的
请注意我对“初始化”一词的使用。在解析定义类的二进制数据时,类被初始化为构造类对象的一部分。
没有什么可以阻止特定的 ClassLoader 实现将它看到的所有类的二进制文件加载到内存中,但它不能完全加载这些类,直到它们被请求而不违反 JLS。
有关常见的 ClassLoader 实现,请参阅 URLClassLoader。