JVM-类加载-双亲委派

1.JDK-JRE-JVM
xxx.java 经过编译生成一个class字节码文件,class文件要在JVM虚拟机上才能运行。
JVM是用来运行.class字节码文件的;java要想在操作系统运行除了jvm还要有核心类库,核心类库就在jre上面;JDK是java开发工具,包含jre和jvm;

C:\Users\13267>java -version
java version "1.8.0_131"
Java(TM) SE Runtime Environment (build 1.8.0_131-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.131-b11, mixed mode)

java -version查看安装的jdk版本等信息。java是跨平台的,编译好的class文件可以在windows,Linux操作系统运行。mixed mode,解释执行和编译执行混合的,代码用到的次数特别多的就会编译成一个本地的编译。
xxx.java文件用javac命令生成xxx.class字节码文件,classLoader类装载和java类库解释和混合编译通过字节码解释器和JIT即时编译器到执行引擎,然后到OS硬件。
java语言是跨平台的语言,平台无关性;JVM是跨语言的平台,只要编译成字节码符合JVM规范都可以执行。
2.class字节码文件-classFileFormat
class文件是一个二进制的字节流,是由java虚拟机来解释的
java文件,只有一个类名
在这里插入图片描述
class字节码文件,含有一个无参构造,默认会添加一个无参构造方法;
在这里插入图片描述
显示的二进制字节码文件,是01组成
在这里插入图片描述
16进制打开的形式。CA FE BA BE开头格式,16进制转为10进制可以查看下面编码代表什么,0000表示0是Minor Version,0034是52表示是jdk1.8版本,0010是16表示常量池有16-1=15个存储数据,constant_pool_count-1 个常量 从1开始 16-1 是15常量 有一个0存在 有引用指向表示不指向任何一个常量池任何一项。
在这里插入图片描述
javap -v T0100_ByteCode01.class 观察ByteCode命令 java自带的
在这里插入图片描述
idea插件jclasslib 插件 ,Constat Pool常量池是class文件最复杂的一个东西,这个文件包含了jdk版本,这个类名,父类名,类权限,属性,字段,方法,构造方法等信息
在这里插入图片描述

3.Class Cycle java类的生命周期
Class Loading Linking initializing
在这里插入图片描述

  1. Verification
    1. 验证文件是否符合JVM规定
    2. Preparation
    1. 静态成员变量赋默认值
    3. Resolution
    1. 将类、方法、属性等符号引用解析为直接引用
    常量池中的各种符号引用解析为指针、偏移量等内存地址的直接引用
    2 Initializing

    1. 调用类初始化代码 ,给静态成员变量赋初始值
      GC 是垃圾回收,表示结束了。GC 是垃圾回收,表示结束了。静态变量是在类加载的时候执行的,所以静态Static修饰的,加载一次就初始化一次,所以是单例模式的。
/*
    System.out.println(T.count);T被classloader装入内存 然后静态变量赋默认值
    默认值 count=0   t=null
    然后 initializing  初始值
    初始值 count=2  t=new T();  new 执行构造函数 count++
     T.count=3

    public static int count = 2; //0
    public static T t = new T(); // null


    //private int m = 8;

    private T() {
        count ++;
        //System.out.println("--" + count);
    }*/

/*
    System.out.println(T.count);T被classloader装入内存 然后静态变量赋默认值
     默认值 count=0   t=null
    然后 initializing  初始值
    new 执行构造函数
    t = new T(); count++ 是1  然后count赋值2  count=2
    public static T t = new T(); // null
    public static int count = 2; //0

    //private int m = 8;

    private T() {
        count ++;
        //System.out.println("--" + count);
    }*/

4.类加载器
在这里插入图片描述
自下向上分别是加载器的父类加载器关系,每个加载器都有自己的内存。为了安全机制所以有双亲委派 防止自己定义java有的类 在加载的时候代替JDK提供的类。
不同的类处于不同的位置在jdk里,有不同的类加载器进行装载,jvm按需动态加载,采用双亲委派机制。
Bootstrap:加载lib/rt.jar charset.jar等核心类,C++实现在java找不到对应的class,在核心类库的class返回的类加载器都是null;
ExtensionClassLoader加载路径java.ext.dirs;App加载classpath路径下的class。这个路径是自己写的类所在位置;自定义类加载器继承classloader重写findclass方法。
class文件平时在硬盘,被load到内存之后,会创建两块内容,第一是把class文件扔到内存,第二是创建一个class类的对象指向这个第一块内容
在这里插入图片描述
如何自定义类加载器:
classloader源码:
在这里插入图片描述在这里插入图片描述
自定义类加载器就是重写findclass方法:让原本抛出异常的方法正常返回class
在这里插入图片描述

5.双亲委派
在这里插入图片描述
双亲委派就是孩子向父亲方向的类加载器的内存寻找是否被加载,找到就返回,找不到就继续向上找直到到达顶点,然后父亲向孩子节点寻找class并加载,直到结尾都找不到说明就没有这个class,就会抛出异常:classNotFoundException这个异常。
jvm加载class是懒加载,需要才加载。

为什么要有双亲委派?为了安全机制所以有双亲委派 防止自己定义java有的类 在加载;
1.parent是如何指定的?用super(parent)指定;
2.如何打破双亲委派?重写loadClass()方法
3.什么时候打破双亲委派?

  1. JDK1.2之前,自定义ClassLoader都必须重写loadClass()

  2. ThreadContextClassLoader可以实现基础类调用实现类代码,通过thread.setContextClassLoader指定

  3. 热启动,热部署

    1. osgi tomcat 都有自己的模块指定classloader(可以加载同一类库的不同版本)
      在这里插入图片描述
      6.jvm是解释和编译混合的模式
      修改启动时的vm参数即可指定是解释还是编译
      解释:启动快,执行慢;
      编译:启动慢,执行快;
      因为编译是把经常用的代码提前编译成文件存于本地,调用时直接调用
      在这里插入图片描述
      7.懒加载
  4. LazyLoading 五种情况

      1. –new getstatic putstatic invokestatic指令,访问final变量除外
    
         –java.lang.reflect对类进行反射调用时
    
         –初始化子类的时候,父类首先初始化
    
         –虚拟机启动时,被执行的主类必须初始化
    
         –动态语言支持java.lang.invoke.MethodHandle解析的结果为REF_getstatic REF_putstatic REF_invokestatic的方法句柄时,该类必须初始化
    

在这里插入图片描述
因为p是x父类,所以先执行加载p静态资源然后加载X,
输出:

P
X
8
9

1.静态类型:
先load内存,赋默认值,然后调用构造函数赋予初始值
2.对象:
成员变量 new object
1分配空间申请内存 赋默认值
2然后调用构造方法 赋初始值
3内存地址赋予变量

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值