jvm解析一(基本概念)
程序员文章站
2022-06-07 17:14:13
...
一:Java虚拟机与程序的生命周期,如下几种情况Java虚拟机将结束生命周期
1,执行System.exit()方法
2,程序正常执行结束
3,程序执行过程中遇见到了异常或错误而异常终止
4,由于系统错误而导致Java虚拟机进程终止
二:Java程序对类的使用方式
1,主动使用(6种)
1):创建类的实例
2):访问某个类或静态变量,或者对静态变量赋值
3):调用类的静态方法
4):反射(如:Class.forName(“com.fov.IOTest”))
5):初始化一个类的子类
6):Java虚拟机启动的时候被标明的启动类(例如包含main方法的类)
*只有当程序访问类的静态变量或静态方法确实在当前类或当前接口中定义时,才可以认为是对类或接口的主动使用
当Java虚拟机初始化一个类的时候,要求它所有的父类都要被初始化,但是这不适合接口
*1):在初始化一个类的时候,并不会初始化它实现的接口
*2):在初始化一个接口的时候,并不会初始化它的父接口
因为一个父接口并不会因为它的子接口或者实现类被初始化而被初始化,只有当程序首次使用特定接口的静态变量的时候才会被初始化。
2,被动使用
除去主动使用外的都为被动使用
Java虚拟机必须在每个类或者接口被首次主动使用的时候才初始化他们
三:类的加载,连接与初始化
1,加载:是将类的.class文件的二进制文件读到内存中,将其放在运行时数据区的方法区里面,然后在堆内存创建一个java.lang.Class对象,用来封装在方法区内的数据结构。
1)加载类的方式:
1)),从本地系统中直接加载
2)),通过网络下载.class文件
3)),从zip,jar等归档文件中加载.class文件
4)),从专有的数据库中提取.class文件
5)),将Java源文件动态的编译为.class文件
2)类加载器种类:
1)),Java虚拟机自带的加载器
1))):根类加载器(Bootstrap)(c++编写无法在java代码中获得该类)
2))):扩展类加载器(Extension)(java实现)
3))):系统加载器(System)(java实现)
2)),用户自定义的类加载器
1))):java.lang.ClassLoader的子类
2))):用户可以通过定制类的加载方式
3),类加载器时间
1)):JVM允许类加载器在预料到某个类将要被使用的时候就预先加载它,如果预先加载的过程中遇到了某.class文件缺失或者错误,那么类加载器在程序首次使用该类的时候才报告错(LinkageError错误)
2)):如果该类一直没有被程序主动使用,那么类加载器就不会报告错误。
4),类加载器的父亲委托机制(Parent Delegation)
1)):根加载器(Bootstrap):该加载器没有父加载器。它负责加载虚拟机的核心类库,如 :java.lang.*,根加载器从系统属性sun.boot.class.path所指定的目录中加载类库,根加载器的实现依赖地层操作系统,它并没有继承java.lang.ClassLoader类
2)):扩展类加载器(Extension):它的父加载器为根类加载器〈父子加载器并不一定是继承关系〉,它从java.ext.dirs系统属性所指的目录中加载类库,或者从JDK的安装目录的jre//lib//ext子目录下加载类库,如果把用户创建的JAR文件放在这个目录下会自动被加载,该类是java.lang.ClassLoader类的子类。
3)):系统类加载器(System),也称为应用类加载器,它的父加载器为扩展加载器,它从环境变量classpath或者系统属性java.class.path所指定的目录加载类,它是用户自定的类加载器的默认父加载器,系统加载器是纯java类,是java.lang.ClassLoader类的子类。
5),定义类加载器
1)),如果某个类加载器能够加载一个类,那么该类加载器就称为定义类加载器,定义类加载器及起所有的子加载器都称为:初始类加载器
2)),当生成一个自定义的类加载器实例时,如果没有指定它的父加载器,那么系统加载器将是该类的父加载器。
3)),要创建类加载器,只需要扩展java.lang.ClassLoader类,然后覆盖它的findClass(String name)方法即可,该方法根据参数指定的类的名字返回对应的Class对象的引用。
2,连接:
1)验证:确保被加载的类的正确性
类被加载后,就进去到连接阶段,连接就是将已经读入到内存的类的二进制数据合并到虚拟机的运行时环境中去。
验证内容:类文件结构检查,语义检查,字节码验证,二进制兼容性的验证
2)准备:为类的静态常量分配内存,并将其初始化为默认值
3)解析:把类中的符号引用转换为直接引用
3,初始化:为类的静态的变量赋予正确的初始值<用户所赋值>
类的初始化步骤
1),假如该类没有被加载和连接,那就先进行加载和连接
2),假如该类存在直接父类,并且该父类没有被初始化,那就初始化该类的父类(跟构造方法一样)<接口不会,只有当程序首次使用特定接口的静态变量的时候才会导致该接口被初始化>
3),假如该类中存在初始化语句,那就依次初始化这些语句。
类的初始化就是上面的6种主动方式,其他的被动使用都不会导致类的初始化
1,执行System.exit()方法
2,程序正常执行结束
3,程序执行过程中遇见到了异常或错误而异常终止
4,由于系统错误而导致Java虚拟机进程终止
二:Java程序对类的使用方式
1,主动使用(6种)
1):创建类的实例
2):访问某个类或静态变量,或者对静态变量赋值
3):调用类的静态方法
4):反射(如:Class.forName(“com.fov.IOTest”))
5):初始化一个类的子类
6):Java虚拟机启动的时候被标明的启动类(例如包含main方法的类)
*只有当程序访问类的静态变量或静态方法确实在当前类或当前接口中定义时,才可以认为是对类或接口的主动使用
当Java虚拟机初始化一个类的时候,要求它所有的父类都要被初始化,但是这不适合接口
*1):在初始化一个类的时候,并不会初始化它实现的接口
*2):在初始化一个接口的时候,并不会初始化它的父接口
因为一个父接口并不会因为它的子接口或者实现类被初始化而被初始化,只有当程序首次使用特定接口的静态变量的时候才会被初始化。
2,被动使用
除去主动使用外的都为被动使用
Java虚拟机必须在每个类或者接口被首次主动使用的时候才初始化他们
三:类的加载,连接与初始化
1,加载:是将类的.class文件的二进制文件读到内存中,将其放在运行时数据区的方法区里面,然后在堆内存创建一个java.lang.Class对象,用来封装在方法区内的数据结构。
1)加载类的方式:
1)),从本地系统中直接加载
2)),通过网络下载.class文件
3)),从zip,jar等归档文件中加载.class文件
4)),从专有的数据库中提取.class文件
5)),将Java源文件动态的编译为.class文件
2)类加载器种类:
1)),Java虚拟机自带的加载器
1))):根类加载器(Bootstrap)(c++编写无法在java代码中获得该类)
2))):扩展类加载器(Extension)(java实现)
3))):系统加载器(System)(java实现)
2)),用户自定义的类加载器
1))):java.lang.ClassLoader的子类
2))):用户可以通过定制类的加载方式
3),类加载器时间
1)):JVM允许类加载器在预料到某个类将要被使用的时候就预先加载它,如果预先加载的过程中遇到了某.class文件缺失或者错误,那么类加载器在程序首次使用该类的时候才报告错(LinkageError错误)
2)):如果该类一直没有被程序主动使用,那么类加载器就不会报告错误。
4),类加载器的父亲委托机制(Parent Delegation)
1)):根加载器(Bootstrap):该加载器没有父加载器。它负责加载虚拟机的核心类库,如 :java.lang.*,根加载器从系统属性sun.boot.class.path所指定的目录中加载类库,根加载器的实现依赖地层操作系统,它并没有继承java.lang.ClassLoader类
2)):扩展类加载器(Extension):它的父加载器为根类加载器〈父子加载器并不一定是继承关系〉,它从java.ext.dirs系统属性所指的目录中加载类库,或者从JDK的安装目录的jre//lib//ext子目录下加载类库,如果把用户创建的JAR文件放在这个目录下会自动被加载,该类是java.lang.ClassLoader类的子类。
3)):系统类加载器(System),也称为应用类加载器,它的父加载器为扩展加载器,它从环境变量classpath或者系统属性java.class.path所指定的目录加载类,它是用户自定的类加载器的默认父加载器,系统加载器是纯java类,是java.lang.ClassLoader类的子类。
5),定义类加载器
1)),如果某个类加载器能够加载一个类,那么该类加载器就称为定义类加载器,定义类加载器及起所有的子加载器都称为:初始类加载器
2)),当生成一个自定义的类加载器实例时,如果没有指定它的父加载器,那么系统加载器将是该类的父加载器。
3)),要创建类加载器,只需要扩展java.lang.ClassLoader类,然后覆盖它的findClass(String name)方法即可,该方法根据参数指定的类的名字返回对应的Class对象的引用。
2,连接:
1)验证:确保被加载的类的正确性
类被加载后,就进去到连接阶段,连接就是将已经读入到内存的类的二进制数据合并到虚拟机的运行时环境中去。
验证内容:类文件结构检查,语义检查,字节码验证,二进制兼容性的验证
2)准备:为类的静态常量分配内存,并将其初始化为默认值
3)解析:把类中的符号引用转换为直接引用
3,初始化:为类的静态的变量赋予正确的初始值<用户所赋值>
类的初始化步骤
1),假如该类没有被加载和连接,那就先进行加载和连接
2),假如该类存在直接父类,并且该父类没有被初始化,那就初始化该类的父类(跟构造方法一样)<接口不会,只有当程序首次使用特定接口的静态变量的时候才会导致该接口被初始化>
3),假如该类中存在初始化语句,那就依次初始化这些语句。
类的初始化就是上面的6种主动方式,其他的被动使用都不会导致类的初始化
推荐阅读
-
mybatis 的 dao 接口跟 xml 文件里面的 sql 是如何建立关系的?一步步解析
-
教你如何分析每一个元素 知名婚礼摄影师的实战解析
-
2020年新高考一卷语文高考试卷真题及答案解析(附Word版下载)
-
Python 之父再发文:构建一个 PEG 解析器
-
Mybaits 源码解析 (十)----- 全网最详细,没有之一:Spring-Mybatis框架使用与源码解析
-
使用70行Python代码实现一个递归下降解析器的教程
-
解析如何利用一个ASP.NET Core应用来发布静态文件
-
Mybaits 源码解析 (八)----- 全网最详细,没有之一:结果集 ResultSet 自动映射成实体类对象(上篇)
-
Mybaits 源码解析 (九)----- 全网最详细,没有之一:一级缓存和二级缓存源码分析
-
18.DjangoRestFramework学习一之restful规范、APIview、解析器组件、Postman等