java虚拟机的介绍

java虚拟机的介绍

一、JVM基本结构
1.类加载器
2.执行引擎
3.运行时数据区
4.本地库接口

在此借用一下别人画好的图片:
借用别人的图片

Class Files ----> ClassLoader---->运行时数据区---->执行引擎,本地库接口----->本地方法库

二、类的装载顺序:
1.类装载
加载,连接(验证,准备,解析),初始化,使用,卸载;Class保存类的定义或者结构在堆中;
2.初始化:
执行类的构造器,为类的静态变量赋予正确的初始值。
构造器:

1.static变量
2.static{}语句

为了验证是否和上面的加载顺序一致,我们写段测试的代码:

public class Test {
    
    
    // 先写静态方法
    static {
    
    
        total = 3;
    }
	// 再写静态类成员变量
    private static int total = 2;
    public static void main(String[] args) {
    
    
        System.out.println(total);
        total = 4;
        System.out.println(total);
    }
}

输出的结果先是2,后是4;

3.JDK已有的类加载器及双亲委派模式:

  • 启动类加载器:BootstrapClassLoader
    是用本地代码实现的类装入器,它负责将
    <Java_Runtime_Home>/lib下面的类库加载到内存中(比如rt.jar)。由于引导类加载器涉及到虚拟机本地实现细节,开发者无法直接获取到启动类加载器的引用,所以不允许直接通过引用进行操作。

  • 标准扩展(Extension)类加载器:ExtClassLoader
    是由 Sun 的ExtClassLoader(sun.misc.Launcher$ExtClassLoader)实现的。它负责将<Java_Runtime_Home >/lib/ext或者由系统变量java.ext.dir指定位置中的类库加载到内存中。开发者可以直接使用标准扩展类加载器。

  • 系统(System)类加载器:AppClassLoader
    是由 Sun 的AppClassLoader(sun.misc.Launcher$AppClassLoader)实现的。它负责将系统类路径(CLASSPATH)中指定的类库加载到内存中。开发者可以直接使用系统类加载器。

  • 自定义加载器 ---->自定义加载路径

用一个特别简单的例子,通过这个简单的例子,看一下执行调用的加载器顺序:

public class Test {
    
    
    public static void main(String[] args) {
    
    
        ClassLoader classLoader = Test.class.getClassLoader();
        System.out.println(classLoader.toString());
        System.out.println(classLoader.getParent());
        System.out.println(classLoader.getParent().getParent());
    }

}

执行结果:惊喜不惊喜,很神奇吧,一不小心还看到了双亲委派模型鸟!

sun.misc.Launcher$AppClassLoader@18b4aac2
sun.misc.Launcher$ExtClassLoader@3b07d329
null

双亲委派模式介绍:别看下面说的那么多,其实很简单,我给大家讲讲甩锅的故事。
一天,有一个类需要AppClassLoader去加载自己,AppClassLoader不耐烦说找我老子ExtClassLoader去;ExtClassLoader也不是个干事的主,也说找我老子BootstrapClassLoader去。想想这个老老子好苦逼啊!
果然有天,老老子BootstrapClassLoader干腻歪了,大爷我不玩了,ExtClassLoader你自己玩去吧!于是ExtClassLoader就自己干了。
但是天有不测风云,ExtClassLoader有天病了,干不了了,没办法,只能找appClassLoader,并告诉它:“儿啊,老子干不了了,你自己干去吧!”
哈哈哈…大概就是这么个情况了。

1.当ApplicationClassLoader 收到一个类加载请求时,他首先不会自己去尝试加载这个类,而是将这个请求委派给父类加载器ExtensionClassLoader去完成。
2.当ExtensionClassLoader收到一个类加载请求时,他首先也不会自己去尝试加载这个类,而是将请求委派给父类加载器BootstrapClassLoader去完成。
3.如果BootstrapClassLoader加载失败(在<JAVA_HOME>\lib中未找到所需类),就会让ExtensionClassLoader尝试加载。
4.如果ExtensionClassLoader也加载失败,就会使用Application ClassLoader加载。
5.如果ApplicationClassLoader也加载失败,就会使用自定义加载器去尝试加载。

三、运行时数据区:
java虚拟机在执行java程序的过程中会把它所管理的内存划分为若干个不同的数据区域。这些区域有各自的用途,以及创建和销毁的时间,有的区域随着虚拟机进程的启动而一直存在,有些区域则是依赖用户线程的启动和结束而建立和销毁。
数据区的划分大致如下图所示:
蓝色:所有线程共享的数据区,随着虚拟机进程启动而一直存在。
橙色:线程私有的隔离数据区,随着用户线程的启动和结束而建立和销毁
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_37488998/article/details/109764361