2020-08-27JVM大局观

目录

一、官网眼中的JVM

二、JVM相关知识点

1.JVM是什么?

​2.JDK,JRE,jVM 关系区别

jdk(Java Development Kit       //Java开发工具包)

jre(Java runtime environment     //Java运行环境)

jvm(Java Virtual Machine    //Java虚拟机)

3.javac的过程

4.类的在JVM中的加载过程

4.双亲委派机制

三.课后小结练习



一、官网眼中的JVM

           

二、JVM相关知识点

1.JVM是什么?

    他是整合java程序多平台运行的根本,因为他屏蔽了不同操作系统的底层差异。

       2.JDK,JRE,jVM 关系区别

jdk(Java Development Kit       //Java开发工具包)

       是包含jre与jvm的超集。JDK中包含JRE,在JDK的安装目录下有一个名为jre的目录,里面有两个文件夹bin和lib,在这里可以认为bin里的就是jvm,lib中则是jvm工作所需要的类库,而jvm和 lib和起来就称为jre。

       JDK是整个JAVA的核心,包括了Java运行环境JRE(Java Runtime Envirnment)、一堆Java工具(javac/java/jdb等)和Java基础的类库(即Java API 包括rt.jar)。

jre(Java runtime environment     //Java运行环境)

        是运行基于Java语言编写的程序所不可缺少的运行环境。也是通过它,Java的开发者才得以将自己开发的程序发布到用户手中,让用户使用。

  JRE中包含了Java virtual machine(JVM),runtime class libraries和Java application launcher,这些是运行Java程序的必要组件。

  与大家熟知的JDK不同,JRE是Java运行环境,并不是一个开发环境,所以没有包含任何开发工具(如编译器和调试器),只是针对于使用Java程序的用户。

jvm(Java Virtual Machine    //Java虚拟机)

       就是我们常说的java虚拟机,它是整个java实现跨平台的最核心的部分,所有的java程序会首先通过javac编译为.class的类文件,这种类文件可以在虚拟机上执行。

  也就是说class并不直接与机器的操作系统相对应,而是经过虚拟机(相当于中间层)间接与操作系统交互,由虚拟机将程序解释给本地系统执行。

  只有JVM还不能成class的执行,因为在解释class的时候JVM需要调用解释所需要的类库lib,而jre包含lib类库。

  JVM屏蔽了与具体操作系统平台相关的信息,使得Java程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。

所有的程序只要有java虚拟机的支持,那么就可以实现程序的执行,并且不同的操作系统上会有不同版本的jvm。

       jvm相当于一个容器,放到不同的操作系统中,因为编写的Java程序经过编译后生成的字节码可以被JVM识别,JVM为程序运行屏蔽了底层操作系统的差异

一个java程序的运行如下图

3.javac的过程

4.类的在JVM中的加载过程

类的加载过程分为三步:加载-链接-初始化

加载:将class文件加载到内存中,通过类的权限和包名来找class文件,

链接分为三步:

         验证-准备-解析  验证是验证.class二进制文件的合法性,验证class文件的开头,版本等等。

         准备就是对一些类的静态变量赋初始默认值

         注意举例:public static int a = 1; 针对该变量a,在该阶段,会为a分配内存,且初始化默认值。
这里不会解析到 a =1,这里只会根据数据类型来决定默认值,即int–0,double–0.0,boolean–false,object–null,等,至于执行 a = 1 的操作,是在后续的初始化阶段完成。

         解析:将对应的符号引用转换为直接引用

初始化:

    class的初始化过程

     

    class的初始化时机有6种

         1,类的实例创建的四种方式(new,class反射,克隆,反序列化),可看下边链接

     https://blog.csdn.net/qq_42977042/article/details/82457513

        2.访问类中的某个静态变量,或者对静态变量进行赋值

        3.主动调用类的静态方法

        4.Class.forName("包类名")

        5.完成子类的舒适化,也会完成对本类的初始化,即先初始化父类,在找自己

         6.该类是程序引导入口例如:main入口

/** *  类加载时静态你成员变量的赋值过程: * * 一:loadClass(类加载) * *

1. 将class对象加载到内存中 * *

2. 给class对象的静态成员变量赋默认值 * *

3. 给class对象的静态成员变量赋初始值 * *

二:newObject(创建对象) * *

1. 给Object对象申请内存空间 * *

2. 将Object对象加载到内存 * *

3. 给Object对象的静态成员变量赋默认值 * *

4. 给Object对象的静态成员变量赋初始值 */

public class D03ClassLoaderProcedure {

public static void main(String[] args) {

// ----- 结果为:3

System.out.println("count01 -- " + Count_01.count);

// ----- 结果为:2

System.out.println("count02 -- " + Count_02.count);

}

/** *

1. 将 Count_01 对象加载到内存 *

2. 给 count 属性赋默认值:0 *

3. 给 count_01 属性赋默认值:null *

4. 给 count 属性赋初始值:2 *

5. 给 count_01 属性对象赋初始值:new Count_01() * 注意:此时的 count 值为:2,在第 5 步给 count_01 属性赋初始值时会调用 Count_01 的构造方法 * 所以:count 会 ++,最终 count 值为:3 */

private static class Count_01 {

public static int count = 2;

public static Count_01 count_01 = new Count_01();

private Count_01() { count++; }

}

/** *

1. 将 Count_02 对象加载到内存 *

2. 给 count_02 属性赋默认值:null *

3. 给 count 属性赋默认值:0 *

4. 给 count_02 属性赋初始值:new Count_02() *

5. 给 count 属性赋默认值:2 * 注意:在第 4 步给 count_02 属性赋初始值时会调用 Count_02 的构造方法,此时的 count 还没有赋初始值,只有默认值,所以此时 count为:0,count++为:1 * 在第 5 步给count 属性赋默认值时会用 2 覆盖 count++:1 的值,所以 count 最终值为:2

*/

private static class Count_02 {

public static Count_02 count_02 = new Count_02();

public static int count = 2;

private Count_02() { count++; }

}

}

4.双亲委派机制

什么是双亲委派机制
当某个类加载器需要加载某个.class文件时,它首先把这个任务委托给他的上级类加载器,递归这个操作,如果上级的类加载器没有加载,自己才会去加载这个类。


双亲委派机制的作用
1、防止重复加载同一个.class。通过委托去向上面问一问,加载过了,就不用再加载一遍。保证数据安全。
2、保证核心.class不能被篡改。通过委托方式,不会去篡改核心.clas,即使篡改也不会去加载,即使加载也不会是同一个.class对象了。不同的加载器加载同一个.class也不是同一个Class对象。这样保证了Class执行安全。

 BootstrapClassLoader
称为启动类加载器,是Java类加载层次中最顶层的类加载器,负责加载JDK中的核心类库,如:rt.jar、resources.jar、charsets.jar等,如java.lang.Integer等

ExtClassLoader称为扩展类加载器,主要负责加载Java的扩展类库,默认加载JAVA_HOME/jre/lib/ext/目录下的所有jar包或者由java.ext.dirs系统属性指定的jar包.放入这个目录下的jar包对AppClassLoader加载器都是可见的(因为ExtClassLoader是AppClassLoader的父加载器,并且Java类加载器采用了委托机制).

AppClassLoader应用类加载器,又称为系统类加载器,负责在JVM启动时,加载来自在命令java中的classpath或者java.class.path系统属性或者CLASSPATH操作系统属性所指定的JAR类包和类路径.

三.课后小结练习

关于JVM内容以下说法不正确的是(BD)
A  JVM是Java平台的重要组成部分.负责屏蔽操作系统及硬件的差异.
B  JVM是JAVA虚拟机只能运行JAVA语言的代码.
C  JVM是一个虚拟的计算机器.其拥有独立的指令集和不同的运行时内存区域
D  JDK是整个JAVA语言能做到 Write Once Run Anywhere的根本

以下哪个类加载器会加载java.lang.Integer(A)
A  BootstrapClassLoader
B  ExtClassLoader
C  AppClassLoader
D  CustomClassLoader

已知S extends F 类,请问以下哪个选项不会触发S类的初始化(C)
A Class.forName(“xxxx.S”)
B 调用S的sayHi的静态方法
C 调用F的sayHello的静态方法
D F s = new S();

关于类加载机制以下说法不正确的是(D)
A 双亲委派可以避免类的重复加载
B 双亲委派保护应用程序安全,防止核心环境遭受破坏
C 自定义classLoader重写loadClass方法可破坏双亲委派机制
D ClassPath环境变量下的class文件由ExtClassLoader负责加载

 

所以不管是什么语言,只要能编译成合法的规范的class文件,我jvm都能让其运行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值