一个Java类的完整的生命周期会经历加载、连接、初始化、使用和卸载五个阶段。
JVM(Java 虚拟机)中的几个比较重要的内存区域
- 方法区:在Java的虚拟机中有一块专门用来存放已经加载的类信息、常量、静态变量以及方法代码的内存区域,叫做方法区。
- 常量池:是方法区的一部分,主要用来存放常量和类中的符号引用等信息。
- 堆区:用于存放类的对象实例。
- 栈区:也叫Java虚拟机栈,是由一个一个的栈帧组成的后进先出的栈式结构,栈帧中存放方法运行时产生的局部变量、方法出口等信息。当调用一个方法时,虚拟机栈中就会创建一个栈帧存放这些数据,当方法调用完成时,栈帧消失,如果i方法中调用了其他方法,则继续在栈顶创建新的栈帧。
初始化
如果一个类被直接引用,就会触发类的初始化。在Java中,直接引用的情况有:
- 通过new关键字实例化对象、读取或设置类的静态变量、调用类的静态方法。
- 通过反射方式执行以上三种行为。
- 初始化子类的时候,会触发父类的初始化。
- 作为程序入口直接运行时(也就是直接调用main方法)
- 除了以上四种情况,其他使用类的方法叫做被动引用,而被动引用不会触发类的初始化。
卸载
在类使用完之后,如果满足下面的情况,类就会被卸载。
- 该类所有的实例都已经被回收,也就是Java堆中不存在该类的任何实例。
- 加载该类的ClassLoader已经被回收
- 该类对应的java.lang.Class对象没有任何地方被引用,无法在任何地方通过反射访问该类的方法。