JVM体系汇总
类加载过程
类的加载为三个阶段:加载,链接,初始化
加载:
- 由类加载器负责将硬盘中的class文件加载到内存中
- 原来静态的数据结构转化为方法区的动态数据结构,
- 在堆中生成class对象
链接分为三个阶段:验证,准备,解析
**验证:**查看class文件中的字节流是否符合虚拟机要求
准备:为class对象中的静态变量分配内存,并初始化
解析:将类中的逻辑引用变为内存中的直接引用
初始化:初始化阶段,才开始执行类中定义的java代码,;初始化是调用类构造器的过程,并为静态变量赋值
类什么时候加载
- new一个对象
- 使用反射创建一个对象(Class.forName())
- 调用类中的静态变量,静态方法
- 初始化子类,父类会加载
类加载器
概念:通过一个类的全限定型类名获取该类的二进制字节流叫做类加载器
类加载器分为四种:
- Bootstrap ClassLoader:负责加载一些java核心类库,不是java语言写的,无法被java程序直接引用
- Extension ClassLoader:加载一些java的扩展库 jdk目录下jre/lib/ext
- Application ClassLoader:java应用的类都是通过它加载的
- 自定义类加载器:继承ClassLoader
双亲委派机制?为什么需要双亲委派模型
当一个类加载收到类的加载时,首先不会自己去加载,而是尝试着向父级加载器请求,看父级是否加载,否则子加载器才会尝试自己去加载类
- 为了防止内存中出现多个相同的字节码,避免类的重复加载.
- 如果没有双亲委派机制,用户就可以自定义一个java.lang.string,这时就无法保证类的唯一性
打破双亲委派模型
自定义类加载器,继承ClassLoader类,重写loadClass方法和findClass方法
示例一:Tomcat
Tomcat中,应用的类加载器优先自行加载应用目录下的class,并不是先委派给父类加载器,加载不了才会委派给父加载器
-
在webapp中的class和lib包中,需要相互隔离,不能出现一个应用中加载的类库会影响另一个应用的情况,对于许多应用,需要有共享的lib以便不浪费资源
-
与jvm一样的安全性问题,防止无意破坏
-
热部署