JVM 类加载过程、运行时数据区

类加载器
  类加载过程
    加载
      将类的class文件读入到内存中,并为之创建一个java.lang.class对象
    链接
      验证
        文件格式验证
          主要验证字节流是否符合Class文件格式规范,并且能被当前的虚拟机加载处理。例如:主,次版本号是否在当前虚拟机处理的范围之内。常量池中是否有不被支持的常量类型。指向常量的中的索引值是否存在不存在的常量或不符合类型的常量。
        元数据验证
          对字节码描述的信息进行语义的分析,分析是否符合java的语言语法的规范。
        字节码验证
          最重要的验证环节,分析数据流和控制,确定语义是合法的,符合逻辑的。主要的针对元数据验证后对方法体的验证。保证类方法在运行时不会有危害出现。
        符号引用验证
          主要是针对符号引用转换为直接引用的时候,是会延伸到第三解析阶段,主要去确定访问类型等涉及到引用的情况,主要是要保证引用一定会被访问到,不会出现类等无法访问的问题。
      准备
        类准备阶段负责为类的静态变量分配内存,并设置默认初始值。
      解析
        将类的二进制数据中的符号引用替换成直接引用。说明一下:符号引用:符号引用是以一组符号来描述所引用的目标,符号可以是任何的字面形式的字面量,只要不会出现冲突能够定位到就行。布局和内存无关。直接引用:是指向目标的指针,偏移量或者能够直接定位的句柄。该引用是和内存中的布局有关的,并且一定加载进来的。
    初始化
      初始化是为类的静态变量赋予正确的初始值
  类加载时机
    创建类的实例,也就是new一个对象
    访问某个类或接口的静态变量,或者对该静态变量赋值
    调用类的静态方法
    反射(Class.forName("com.lyj.load"))
    初始化一个类的子类(会首先初始化子类的父类)
    JVM启动时标明的启动类,即文件名和类名相同的那个类
  类的加载机制
    全盘负责
      所谓全盘负责,就是当一个类加载器负责加载某个Class时,该Class所依赖和引用其他Class也将由该类加载器负责载入,除非显示使用另外一个类加载器来载入
    双亲委派
      所谓的双亲委派,则是先让父类加载器试图加载该Class,只有在父类加载器无法加载该类时才尝试从自己的类路径中加载该类。通俗的讲,就是某个特定的类加载器在接到加载类的请求时,首先将加载任务委托给父加载器,依次递归,如果父加载器可以完成类加载任务,就成功返回;只有父加载器无法完成此加载任务时,才自己去加载。
    缓存机制
      缓存机制。缓存机制将会保证所有加载过的Class都会被缓存,当程序中需要使用某个Class时,类加载器先从缓存区中搜寻该Class,只有当缓存区中不存在该Class对象时,系统才会读取该类对应的二进制数据,并将其转换成Class对象,存入缓冲区中。这就是为什么修改了Class后,必须重新启动JVM,程序所做的修改才会生效的原因。

运行时数据区
   虚拟机栈
     局部变量表
       8种基本数据类型
       对象引用(reference类型)
       returnAddress类型
     操作数栈
     动态链接
     方法返回地址
   本地方法栈
   程序计数器
   
   方法区

原文地址:https://www.cnblogs.com/jiehanshi/p/14455599.html