JVM的内存分析和类加载过程学习

Java 内存分区结构:

:存放new的对象和数组,可以被所有的线程共享,不会存放别的对象引用

:存放基本类型(包含具体数值的)、引用对象的变量(该引用对象在堆的具体地址

方法区:存放class对象,static变量,可以被所有的线程共享


类的加载过程:

加载 - 链接 - 初始化

加载:

class字节码文件加载到内存中,将静态数据放到方法区,成为运行时数据结构,然后生成Class对象

类的加载阶段过程

  1. java文件
  2. 通过java c编译成字节码.class文件
  3. 引导类加载器:用C++编写,无法直接获取,负责JAVA平台核心库,用来装载核心类库
  4. 扩展类加载器:负责jre/lib/ext目录下的jar包或者-D java.ext.dirs 指定目录下的jar包装入工作库
  5. 系统类加载器:负责 java -classpath 或者- D java.class.path所指的目录下的类和jar包装入工作,是最常用的加载器
  6. 自定义类加载器:可以自定义加载特定的类(可以用来实现一些加密操作)

类缓存:一旦类加载到jvm,不管有没有使用,都会持续缓存一段时间,不过JVM的垃圾回收机制可以回收这些Class对象

双亲委派机制:属于JVM类加载的安全机制,JVM会优先加载更核心底层的类(引导类-扩展类-系统类),如果出现其余重名的话,则不会加载。例如,引导类加载器存在Object类,那么自定义的Obeject是不会被加载的。

链接:(将Java二进制代码合并到JVM的运行状态中的过程)

验证 - 准备 - 解析

验证:确保加载进来的类符合规范,没有安全问题

准备:分配内存,初始化static变量同时赋予初始值,这些内存都在方法区分配

解析:虚拟机常量池内的符号引用(常量名)替换为直接引用地址的过程

初始化:

执行每个类的()方法,JVM会把所有赋值动作和精通代码块的语句合并,封装成clinit方法来初始化

如果有父类,会先执行父类的clinit方法

jvm会保证一个类的clinit方法在多线程环境中被正确加锁和同步

类什么时候触发初始化:
#主动引用:
1.new 对象
2.反射获取对象

#被动引用:
1.调用静态常量时不会触发初始化(子类调用父类也一样)
2.数组声明元素类型时不会触发初始化
posted @ 2021-08-02 22:43  没离开过o  阅读(70)  评论(0)    收藏  举报