JVM运行和类加载过程

首先,关于JVM中的方法区、堆、栈

  • 方法区:存放代码;静态变量,静态方法,字符串常量,(在堆内存中)
  • 堆:存放所有new出来的对象;
  • 栈:存放基本类型的变量数据和对象的引用,但对象本身不存放在栈中,而是存放在堆(new
    出来的对象)或者常量池中(对象可能在常量池里)(字符串常量对象存放在常量池中。
    来自https://www.cnblogs.com/xiaowangbangzhu/p/10366200.html
    JVM内存示意图
    在这里插入图片描述

java虚拟机严格规范了初始化的6种情况:

  1. 四条指令:new\getstatic\putstatic\invokestatic;常见的是:当有new关键字实例化对象的时候、读取或设置一个类的静态字段、调用一个类的静态方法的时候
  2. 反射调用时,类没有初始化,需要触发
  3. 有继承时,子类初始化的时候,父类必须先初始化;
  4. 当要执行main方法的主类时,需要先初始化这个主类
  5. 使用jdk1.7的时候,如果java.lang.invoke.MethodHandle实例最后的解析结果是REF_getStatic、REF_putStatic、REF_invokeStatic的方法句柄,且这个方法句柄所对应的类没有初始化,需要出发初始化。
  6. JDK8中 default修饰的方法的接口,其实现类发生初始化的时候,该接口也需要立即初始化。

类加载过程:

  1. JVM会先去方法区中找有没有类对应的.class存在,如果有,就直接使用;如果没有,就把对应类的.class加载到方法区;
  2. 将.class加载到方法区的时候,分为两部分,首先将非静态内容加载到方*法区的非静态区域内;
  3. 再将静态内容加载到方法区的静态区域内,加载完成后,对所有的静态成员变量进行默认初始化;
  4. 所*有静态成员变量默认初始化后,进行显示赋值;再执行静态代码块;(执行静态代码块和静态成员变量显示赋值无先后顺序,与代码顺序有关,谁在前面先执行谁)
  5. 如果有继承关系,加载子类的时候会先加载父类,在加载子类。

在这里插入图片描述

类加载器的层次结构(树状结构)

  • 引导类加载器: C来实现的,后面三个均是java实现的,用来加载java的核心库(JAVA_HOME/jre/lib/rt.jar,或sun.boot.class.path路径下的内容),是用原生代码实现的,并不是继承自java.lang.ClassLoader。加载扩展类和应用程序类加载器,并指定他们的父类加载器。
  • 扩展类加载器:用来加载java的扩展库(JAVA_HOME/jre/ext/*.jar,或java.ext.dirs路径下内容)。Java虚拟机的实现会提供一个扩展目录库,该类加载器在此目录里面查找并加载java类。
  • 应用程序类加载器:它根据java应用的类路径(claspath、java.class.path)。一般来说,java应用的类都是由它来完成加载的。
  • 自定义类加载器: 开发人员可以通过继承java.lang.ClassLoader类的方式实现自己的类加载器。
    **java.class.ClassLoader作用在这里插入图片描述
    **

类加载器机制
Java中,一个类用其全限定类名(包括包名和类名)作为唯一标识。
JVM中,一个类用其全限定类名和其类加载器作为唯一标识(类名、包名、加载器的实例)。

  • 全盘负责制:该类所有依赖的和引用的其他类将由该类的加载器负责载入,除非显式使用另外的加载器载入。
  • 父类委托:先委托父类加载器加载目标类,找不到时再从自己的类路径中查找并加载目标类,确保类只被加载过一次。
  • 缓存机制:保证所有加载过的类都会被缓存,当需要使用时,先从缓存区中搜索,缓存不存在该类时,系统才会读取该类对应的二进制数据,将期转换成Class对象,放入缓存区中。

类加载器执行步骤
类加载器加载Class大致经过如下8个步骤:

  1. 检测此类是否载入过(即在缓存区是否存),有进入第8步,没有执行第2步。
  2. 如果父类加载器存在,执行第3步;否则跳到第4步执行。
  3. 请求父类加载器载入目标类,如果成功跳到第8步,否则执行第5步。
  4. 请求根类加载器载入目标类,如果成功跳到第8步,否则执行第7步。
  5. 当前类加载器尝试寻找Class文件,如果找到则执行第6步,否则跳到第7步。
  6. 从文件中载入Class,成功载入后跳到第8步。
  7. 抛出ClassNotFoundException异常。
  8. 返回对应的java.lang.class对象
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值