1. 类初始化和类加载
1.1 创建对象的过程
在 JVM 中,创建一个新对象大致经历四个关键步骤:类加载检查、分配内存空间、初始化零值操作、进行必要设置(对象头),最后执行构造方法。
类加载:当虚拟机遇到 new 关键字时,会先检查对应类是否已加载。若未加载,则优先执行类加载流程,随后才继续执行 new 操作。
分配内存空间:在堆内存中为对象开辟一段连续的空间。
初始化零值操作:将对象实例变量初始化为默认零值(对象头信息除外)。
进行必要的设置:例如给对象头写入类的元数据、对象的哈希码、分代年龄等信息。
执行构造方法:调用对应的 <init> 方法完成对象初始化。
1.2 对象的生命周期
对象的生命周期主要包含三个阶段:创建、使用、销毁。
- 创建:即上述的实例化过程。
- 使用:通过引用访问该对象的成员或方法。
- 销毁:当对象不再被任何路径可达的引用链指向时,会被标记为垃圾并回收。
1.3 类加载器
JVM 内置了三种类加载器:
- 启动类加载器 (Bootstrap):负责加载 Java 核心库中的类,通常由 C++ 实现。
- 扩展类加载器 (Extension):负责加载扩展目录下的类,如框架提供的类。
- 应用程序类加载器 (Application):负责加载用户自定义的类,是默认的类加载器。
1.4 双亲委派模型
双亲委派模型遵循'向上委派,向下加载'的原则。当一个类加载器收到加载请求时,不会立即尝试自己加载,而是先将请求委派给父类加载器。依次类推,直到委派给最顶层的启动类加载器。如果父加载器无法加载,子类才会尝试自己加载。
这种机制主要有以下作用:
- 保证类的唯一性:确保一个类只会被一个类加载器加载一次,避免重复加载。
- 保证安全性:防止用户自定义的类(如
java.lang.String)覆盖核心库类,保护系统安全。 - 形成隔离和分层:不同层级的加载器负责不同范围的类,既高效又清晰。
- 简化加载流程:统一的委派机制减少了类加载逻辑的复杂度。
1.5 类加载的过程
从宏观上看,类加载分为五个阶段:加载、连接、初始化、使用、卸载。其中连接阶段可细分为验证、准备和解析,因此微观上常称为七个步骤。
- 加载:通过全限定名找到二进制字节码文件,将其转换为方法区内的运行时数据结构。
- 验证:确保字节码符合 JVM 规范,包括文件格式校验、元数据验证、字节码验证等。
- 准备:为类的静态变量分配内存并设置默认初始值。
- 解析:将常量池内的符号引用替换为直接引用。
- 初始化:执行类构造器
<clinit>方法,处理父类和子类的静态成员及静态代码块。 - 使用:程序运行期间对类进行操作。
- 卸载:当类的所有实例被回收、类加载器被回收且该类未被引用时,可被卸载。
2. 垃圾回收
2.1 垃圾回收介绍
传统开发需要手动管理内存释放,而垃圾回收(GC)机制能自动回收无用内存。这不仅提高了开发效率,也有效避免了内存溢出和内存泄漏等问题。


