美文网首页
类加载视频观看笔记

类加载视频观看笔记

作者: 王小杰at2019 | 来源:发表于2018-09-21 11:08 被阅读6次

[toc]

以下代码运行的结果是什么

package cn.wyj.jvm;

class Singleton {
//    private static Singleton singleton = new Singleton();
    public static int a;
    public static int b = 0;
    private static Singleton singleton = new Singleton();

    private Singleton() {
        a++;
        b++;
    }

    public static Singleton getInstance() {
        return singleton;
    }
}

public class MyTest1Static {
    public static void main(String[] args) {
        Singleton singleton= Singleton.getInstance();

        System.out.println(singleton.a);
        System.out.println(singleton.b);
    }
}

运行结果是

1
1

如果注释内容调换后执行结果是

1
0

1. java虚拟机会结束程序生命周期

  1. 执行System.exit();
  2. 程序正常结束
  3. 程序在执行过程中遇到异常
  4. 由于操作系统出现的错误导致java虚拟机进程终止

类的加载链接初始化

  1. 加载,查找并加载类的二进制文件
  2. 链接,
    • 验证:确保类加载的类的正确性
    • 准备:为<span style="color:red">静态变量</span>分配内存,并将其初始化为默认值
    • 解析:把类中的符号引用转换为直接引用
  3. 初始化,为类的静态变量赋予正确的初始值

加载流程图

image

java对类的使用方式

JVM规范没有对类加载时机做强制越说但是的对初始化时机有规定
所有的java虚拟机实现必须在每个类或者接口被java程序<span style="color:red;;font-weigth:bold"> "首次主动使用"</span>时才会初始化他们

  1. 主动使用(6种)

    • 创建类的实例
    • 访问某个类的静态变量,或者对静态变量赋值
    • 调用类的静态方法
    • 反射例如 Class.forName
    • 初始化一个类的子类
    • java虚拟机启动时被标明为启动类的类
  2. 被动使用

    • 通过子类引用父类的静态字段,为子类的被动使用,不会导致子类初始化
    • 通过数组定义类引用类,为类的被动使用,不会触发此类的初始化
    • 常量在编译阶段会存入调用方法所在的类的常量池

类的加载

类的加载是指将类的class文件读入到内存当中,将其存放在运行时数据区的方法区内,然后再堆区创建一个java.lang.Class对象,用来封装类在方法区内数据结构

image

Class.class class对象是由java虚拟机创建,不能自己创建

  /*
     * Private constructor. Only the Java Virtual Machine creates Class objects.
     * This constructor is not used and prevents the default constructor being
     * generated.
     */
    private Class(ClassLoader loader) {
        // Initialize final field for classLoader.  The initialization value of non-null
        // prevents future JIT optimizations from assuming this final field is null.
        classLoader = loader;
    }
  1. class类的加载方式

    • 从本地系统直接加载
    • 通过网络下.class文件
    • 从zip,jar等归档文件中读取
    • 从专有数据库中提取.class文件
    • 将java文件动态编译为.class文件
  2. 类加载最终产品是位于堆区的Class对象

  3. class对象封装了类在方法区的数据结构,并向程序员提供了访问方法区数据结构的接口

  4. 类加载器

    • java虚拟机自带
      • 根类加载器(Bootstrap),c++编写,无法获取
      • 扩展加载器(Extension),java编写
      • 系统加载器(System),java编写
    • 用户自定义类加载器
      • java.lang.ClassLoader 子类
      • 用户定制自己的类加载器

类加载器并不需要等到某个类首次主动使用时在加载
JVM规范允许加载器在预料某个类将要被使用时就预先加载他,如果在预想加载的过程中遇到.class文件确实或者存在错误,类加载器必须首次主动使用该类时才报错(LinkageError错误)
如果这个类一直没有被程序主动使用,那么类加载器就不会报告错误

  1. 类的验证
    类被加载后,就I加你入链接阶段,链接就是将已经读入到内存的类的二进制数据合并到虚拟机的运行时环境中去
    • 类文件的结构检查
      • 确保类文件遵从java类文件的固定格式
    • 语义检查
      • 确保类本身符合javascript语言语法规定,比如final类型的类有子类,已经final类型的方法没有被覆盖
    • 字节码验证
      • 确保字节码流可以被java虚拟机安全地执行.字节码流代表java方法(包括静态方法阿和实例方法),它是由被称作操作码的单字节指令组成的序列,每一个操作码后面都跟着一个或多个操作数.字节码验证步骤会检查每个操作码是否合法,即是否有着合法的操作数.
    • 二进制兼容性的验证
      • 确保相互应用的类之间协调一致,流入在Worker类的goto workd 方法中会调用car类的run方法.java虚拟机在验证worker类时,会检查在方法区内是否存在car类的run方法,加入不存在(当Woker类和Car类的版本不兼容就会出现这种文件),就会抛出NoSchMethodError错误.
  1. 类的准备
    在准备阶段,java虚拟机为类的静态变量分配内存,并设置默认的初始值.

  2. 类的解析
    在解析阶段,java虚拟机会吧类的二进制数据中的符号引用替换为直接引用.

  3. 类的初始化
    在初始化阶段,java虚拟机执行类的初始化语句,为类的静态变量赋予初始值,在程序中,静态比那里的初始化有两种途径,

    • 在静态变量生命的处进行初始化
    • 在静态代码块中进行初始化

    初始化步骤

    • 加入这个类还没有被加载和连接,那就先进性加载和连接
    • 假如类存在直接的父类,并且这个父类还没有被初始化,那么久先初始化直接的父类
    • 加入类中存在初始化语句,那就依次执行这些初始化语句

常量对初始化的影响

类的初始化时机
当java虚拟机初始化一个类时,要求他的酥油父类都已经被初始化,但是这条规则不适用于接口

  • 在初始化一个类时,并不会初始化他所实现的接口
  • 在初始化一个接口时,并并不会先初始化它的父接口

程序中对子类的主动使用会导致父类的初始化,对父类的主动使用不会导致子类初始化,例如使用使用Object类不会对所有类实例化

只有当程序访问的静态变量或者静态方法确实在当前类或者当前接口定义时,才可以认为是对类或者接口的主动使用

调用clasLoader类的loadClass方法加载一个类,并不是对类的主动使用,不会导致类的初始化

类加载器

  1. 有两种类型的类加载器
    • Java 虚拟机自带的加载器
      • 根类加载器(Bootstrap)
      • 扩展类加载器(Extension)
      • 系统类加载器(System)
    • 用户自定义的类加载器
      • java.lang.ClassLoader 的子类
      • 用户可以定制类的加载方式
    image
  1. 双亲委托
    Java中ClassLoader的加载采用了双亲委托机制,采用双亲委托机制加载类的时候采用如下的几个步骤:
    1. 当前ClassLoader首先从自己已经加载的类中查询是否此类已经加载,如果已经加载则直接返回原来已经加载的类。
      每个类加载器都有自己的加载缓存,当一个类被加载了以后就会放入缓存,等下次加载的时候就可以直接返回了。
    2. 当前classLoader的缓存中没有找到被加载的类的时候,委托父类加载器去加载,父类加载器采用同样的策略,首先查看自己的缓存,然后委托父类的父类去加载,一直到bootstrp ClassLoader.
    3. 当所有的父类加载器都没有加载的时候,再由当前的类加载器加载,并将其放入它自己的缓存中,以便下次有加载请求的时候直接返回。

相关文章

  • 类加载视频观看笔记

    [toc] 以下代码运行的结果是什么 运行结果是 如果注释内容调换后执行结果是 1. java虚拟机会结束程序生命...

  • Java类加载

    本篇笔记的目标是理解类加载器的架构,学会实现类加载器并理解热替换的底层原理。 什么是类加载 类从被加载到虚拟机内存...

  • JVM学习笔记

    JVM学习笔记 上周观看了圣思园张龙老师所讲的<深入了解JVM>课程,结合自己的理解对有关类加载器的内容(Clas...

  • android 动态加载技术demo

    1.引言 前面写了很多关于java类加载机制的笔记。今天又看了下android动态加载,发现和java加载类真是贴...

  • 手把手带你玩转直播(目录篇)

    视频地址 视频观看地址 笔记目录 'why'带你走进直播世界(一)

  • 什么是VAST,VPAID,VMAP和MRAID?

    你是否曾在线观看视频并在视频顶部看到横幅广告?或观看视频时中途看到广告?使用移动应用时,富媒体广告如何加载到手机上...

  • 化妆品原料、配方、生产工艺、不良反应防治--大总结

    本视频可以到中国大学MOOC观看。 本文为笔记,原创,内容写实。 一、化妆品原料 分类:油性原料、水性原料、粉类原...

  • 深入理解JVM第七章笔记

    深入理解JVM第七章笔记 类加载 虚拟机的类加载机制: 虚拟机把描述类的数据从Class文件加载到内存,并对数据进...

  • 音视频之视频采集

    视频采集 AVFoundation 完成视频采集,做个笔记吧. 初始化页面布局 懒加载需要用的对象 下面是懒加载的...

  • “抖音"短视频APP用户使用行为

    (一)使用时间 通过研究发现,从短视频观看时段上看,早上观看“抖音”短视频的用户, 大多是浏览创意类短视频作品,从...

网友评论

      本文标题:类加载视频观看笔记

      本文链接:https://www.haomeiwen.com/subject/ildanftx.html