JVM的内存分析和类加载过程学习
Java 内存分区结构:
堆:存放new的对象和数组,可以被所有的线程共享,不会存放别的对象引用
栈:存放基本类型(包含具体数值的)、引用对象的变量(该引用对象在堆的具体地址)
方法区:存放class对象,static变量,可以被所有的线程共享
类的加载过程:
加载 - 链接 - 初始化
加载:
class字节码文件加载到内存中,将静态数据放到方法区,成为运行时数据结构,然后生成Class对象
类的加载阶段过程:
- java文件
- 通过java c编译成字节码.class文件
- 引导类加载器:用C++编写,无法直接获取,负责JAVA平台核心库,用来装载核心类库
- 扩展类加载器:负责jre/lib/ext目录下的jar包或者-D java.ext.dirs 指定目录下的jar包装入工作库
- 系统类加载器:负责 java -classpath 或者- D java.class.path所指的目录下的类和jar包装入工作,是最常用的加载器
- 自定义类加载器:可以自定义加载特定的类(可以用来实现一些加密操作)
类缓存:一旦类加载到jvm,不管有没有使用,都会持续缓存一段时间,不过JVM的垃圾回收机制可以回收这些Class对象
双亲委派机制:属于JVM类加载的安全机制,JVM会优先加载更核心底层的类(引导类-扩展类-系统类),如果出现其余重名的话,则不会加载。例如,引导类加载器存在Object类,那么自定义的Obeject是不会被加载的。
链接:(将Java二进制代码合并到JVM的运行状态中的过程)
验证 - 准备 - 解析
验证:确保加载进来的类符合规范,没有安全问题
准备:分配内存,初始化static变量同时赋予初始值,这些内存都在方法区分配
解析:虚拟机常量池内的符号引用(常量名)替换为直接引用地址的过程
初始化:
执行每个类的
如果有父类,会先执行父类的clinit方法
jvm会保证一个类的clinit方法在多线程环境中被正确加锁和同步
类什么时候触发初始化:
#主动引用:
1.new 对象
2.反射获取对象
#被动引用:
1.调用静态常量时不会触发初始化(子类调用父类也一样)
2.数组声明元素类型时不会触发初始化

浙公网安备 33010602011771号