JVM的生命周期
- JVM的启动:通过引导类加载器(加载核心API)创建一个初始类
- JVM运行:执行Java程序,所以执行一个java程序时,其实就是执行一个java虚拟机进程
- JVM退出:
-
-
java程序执行完成或者异常退出
-
OS影响JVM进程
-
手动退出,Runtime(单例 饿汉式)或者System的exit方法
-
内存结构
简图
详细图:
类加载器子系统 
作用:
-
负责将class文件加载到JVM内存中(class文件在文件开头有个特定的文件标识),不负责是否可以运行,由执行引擎决定
-
加载的类信息存放在方法区,叫做DNA元数据模板
类加载过程
类的加载分为三个阶段:加载、链接、初始化
加载
- 通过类名获取定义该类的二进制字节流
- 将这个字节流中的静态存储结构转化为方法区的运行时数据结构
- 在内存中生成一个代表这个类的java.lang.Class对象,提供访问入口
链接
- 验证:确保class文件的字节流中包含的内容是否满足当前虚拟机要求,确保被加载类的正确性,不会影响虚拟机
- 准备:为类变量分配内存并且设置类变量的默认初始值,并且final修饰的static不会设置,因为final在编译时就已经完成了分配,此时会显示初始化;实例变量不初始化
这里的显示初始化是值 int num=1 将num 的值由默认0 初始化为 1
- 解析:将常量池中的符号引用转换为直接引用(初始化之后执行)
初始化
- 初始化就是 类构造器方法 的过程,此方法是编译器自动收集类中的类变量的赋值动作和静态代码块合并而来
- 类构造器方法中的指令按照源文件中的顺序
- 构造器在JVM中是()
- 父类的()执行完成以后,才执行子类的
- 虚拟机要保证一个类的()方法在多线程下加锁
类加载器
- JVM中支持两种类加载器,分别是引导类加载器和自定义类加载器
- 只要是派生于抽象类ClassLoader的类加载器都划分到自定义加载器
- Java核心类都是引导类加载器
为什么需要用户自定义类加载器?
- 隔离加载类:当存在类冲突时,比如引入中间件
- 修改类加载方式
- 扩展加载源
- 防止源码泄漏:防止源码泄漏,会对字节码文件进行加密,自己需要运行,要还原就需要解密,通过自定义
如何实现?
- 继承java.lang.ClassLoader类,实现自定义类加载器即可
- 重写findClass方法
- 如果需求简单,直接继承URLClassLoader,避免覆盖方法和获取字节码流