JVM
1.这个class文件,谁来负责加载到内存中?
- 类加载器
- 类加载器负责从文件系统或者网络中加载Class文件(Class文件在文件开头有特定的文件标识(CA FE BA BE))
- 类加载器(ClassLoader)只负责Class文件的加载,由执行引擎(Execution Engin)决定它是否可以运行。
2.class文件,存在内存哪个位置?
- 类加载器从class文件中抽取类信息并放在方法区中
- 类信息:方法代码,变量名,方法名,访问权限,返回值…
3.Class对象存储在哪里?
- 每当加载器从class文件中加载一个类时,都会加载类信息到方法区中,用时生成一个类对象。
- Class对象可以new对个对象实例。
- Class对象存储在堆里面。
4.一个类进入JVM后,它经历了什么?
-
类的3个时间节点加载
- 虚拟机启动时,执行main()方法
- new对象时
- 读取静态字段或静态方法时
-
类的整个生命周期
- 加载、验证、准备、解析、初始化、使用和卸载(通常在一个阶段执行过程中调用或激活另一个阶段)
- 加载、验证、准备、初始化、卸载发生顺序确定
5.生命周期
-
加载
- 通过一个类的全名(包名+类名)获取此类的二进制字节流
- 将这个字节流所代表的静态存储结构转换为方法区的运行时数据结构
- 在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口
-
验证
- 验证Class文件的内容是否符合当前虚拟机的要求,保证被加载类的正确性,不会危害虚拟机自身安全。
- 四种验证:文件格式验证、源数据验证、字节码验证、符号引用验证。
-
准备
- 为类变量分配内存并且设置该变量的默认初始值。
- 不包含用final修饰的static,final在编译时就分配,准备阶段会显示初始化。
- 不会为实例变量分配初始化,类变量会分配在方法区中,而实例变量是会随对象一起分配到java堆中。
public class Main{ //类变量:分配在方法区中,初始化默认值 public static int a =4; //准备阶段不处理,final在编译阶段就分配好。 public final static int b=2; //实例变量:分配在堆中 public int c =1; } -
解析
- 将常量池内的符号引用转换为直接引用的过程。
- 符号引用:一组符号来描述所引用的目标。
- 直接引用:直接指向目标的指针、相对偏移量或一个间接单位到的目标句柄。
- 将常量池内的符号引用转换为直接引用的过程。
//str 是符号引用,abc是目标
String str = "abc"
System.out.println(str);
//解析后
System.out.println("abc");
-
初始化
-
使用
-
卸载
- 结束类的生命周期
- 执行了System.exit()方法
- 程序正常执行结束
- 程序在执行过程中遇到异常或者错误而异常终止
- 由于操作系统出现错误而导致Java虚拟机进程终止
- 结束类的生命周期
JVM加载class文件由类加载器负责,类信息存储在方法区,Class对象存于堆中。类经历加载、验证、准备、解析、初始化、使用和卸载等阶段,其中加载包括获取二进制字节流并转换为运行时数据结构,验证确保类的正确性,准备阶段分配类变量内存并设置默认值,解析将符号引用转为直接引用,初始化执行静态初始化代码块。
9万+

被折叠的 条评论
为什么被折叠?



