初识JVM虚拟机

导读:本篇文章讲解 初识JVM虚拟机,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

JVM

一、概述

1.特点:

​ 1、一次编译,到处运行

​ 2.自动内存管理

​ 3.自动垃圾回收功能

2.跨平台性图解

在这里插入图片描述

3.java代码执行流程

在这里插入图片描述

总:高级=》汇编=》机器指令

4.通过语言之间的关系,解释上图

在这里插入图片描述

二、认识jvm

1、类加载器

1.1 总流程

在这里插入图片描述

1.2 类加载器的过程

在这里插入图片描述
———-更新2022.03.06
2.类加载器关系分类
在这里插入图片描述

2.1引导类加载器

​ c和c++实现;

​ 为了安全只加载包名为java、javax、sun等包

2.2扩展类加载器

​ 加载JDK安装目录下的jre/lib/ext文件

2.3系统类加载器

系统内部默认的类加载;一般我们平常都是靠他加载的

2.4用户自定义加载器

1、一般靠着上面三个就够了

2、此加载器的目的

​ 隔离加载类、扩展加载源、防止源码泄露、修改类加载方式

自定义方式
在这里插入图片描述

3.总结:类加载器=》就是JVM的入口
在这里插入图片描述

获取类加载的方式
在这里插入图片描述
—–更新2022.03.13

2、双亲委派

概述:

jvm对class文件进行按需加载的方式,当需要的时候才会将class文件加载为class对象。加载class文件的时候,采用双亲委派的方式(任务委派方式),即先将class文件交给父类类加载器执行,父类能干的事给父类干,当父类干不了就给子类干

图解:

在这里插入图片描述

总结双亲委派:

一、工作原理:

1、按需加载class文件成class对象

2、class文件先给子类的类加载器,由子类向上委托

3、由父类开始加载class文件,成功就由当前父类加载,失败交由其子类,以此类推,直到加载完毕,否则会由类加载异常

二、好处:
  • 避免类的重复加载
  • 保护程序安全,防止核心API被随意篡改
    • 自定义类:java.lang.String
    • 自定义类:java.lang.ShkStart(报错:阻止创建 java.lang开头的类)
三、沙箱保护机制
  • 自定义String类,但是在加载自定义String类的时候会率先使用引导类加载器加载,而引导类加载器在加载的过程中会先加载jdk自带的文件(rt.jar包中java\lang\String.class),报错信息说没有main方法,就是因为加载的是rt.jar包中的string类。这样可以保证对java核心源代码的保护,这就是沙箱安全机制
  • 如图,虽然我们自定义了一个java.lang包下的String尝试覆盖核心类库中的String,但是由于双亲委派机制,启动加载器会加载java核心类库的String类(BootStrap启动类加载器只加载包名为java、javax、sun等开头的类),而核心类库中的String并没有main方法

当尝试去写一个包名为java.lang.String的类方法,由于双亲委派的机制,导致在加载class文件的时候,一定是由启动类加载器(Bootstrap【BootStrap启动类加载器只加载包名为java、javax、sun等开头的类】)去加载=》导致自定义的String类方法加载失败

==》更新2022.03.20 12:35 (更新双亲委派【任务模式】)

阶段一总结(JVM类加载器):

在这里插入图片描述

【该问自己的问题,谁干嘛的,怎么干,为什么这么干,不这么干会怎么样】

【不过分深究】

一、加载阶段

1:引导类加载器:

1.1引导类加载器加载只jvm自身需要的类,如包名为java,javax,sun等(例:基础数据类型,string)

1.2c和c++实现的

1.3出于安全考虑

1.4略

2:扩展类加载器

2.1加载jdk目录下的

2.2java实现,继承引导类加载器

2.3略

2.4略

3:系统类加载器

3.1加载java应用的类

3.2java实现,继承扩展类加载器

3.3略

3.4略

4.双亲委派见上篇

二、链接阶段

1:验证

1.1验证是否是合法的字节码文件,cafe bean开头

2:准备

2.1为类变量赋初始值

3:解析

3.1将常量池中的符号引用转化为直接引用

二、运行时数据区

1.概述

i:

初识JVM虚拟机

类加载器工作结束后,进入到运行时数据区(五大模块【本地方法栈,虚拟机栈,堆,方法区,程序计数器】),

由执行引擎来操作运行时数据区

ii:

灰色的为单独线程私有的,红色的为多个线程共享的。即:

  • 线程独有:独立包括程序计数器、栈、本地方法栈
  • 线程间共享:堆、堆外内存(永久代或元空间、代码缓存)

每个线程都会有一块运行时数据区吗?【每一个线程都会有一个栈帧】

初识JVM虚拟机

2.拆分

1.程序计数器:

1.1干嘛:记录下一条指令执行的地址,由执行引擎来执行,原因cup会不停的进行任务切换

1.2怎么干:每一个线程私有的,

1.3目的:确保记录每个线程执行的地址

1.4不这么干的后果:会导致不知道执行哪一行

初识JVM虚拟机

=====》更新2022.03.27(类加载器总结,运行时数据区概述,程序计数器)

2.虚拟机栈:

1)栈和堆的区别:栈是运行的单位,堆是储存的单位
2)每个线程都会创建一个虚拟机栈(每个线程之间的栈都是独立的)

初识JVM虚拟机

3)虚拟机栈的生命周期和线程的生命周期一致
4)栈不存在垃圾回收,不存在GC但是存在OOM
5)栈中的内部结构

局部变量、操作数栈、动态连接、返回地址、附加信息

初识JVM虚拟机

每个线程都会开启一个栈空间,每一个线程中的方法都会以栈帧的方式压入当前线程的栈空间中,每个栈帧中主要有以下几个部分,栈帧的大小主要由局部变量表和操作数栈决定

初识JVM虚拟机

6)局部变量表
7)操作数栈

根据字节码指令向栈中存放数据或取出数据,

作用:存放数据中间结果,作为计算过程中变量的临时存放空间

初识JVM虚拟机

局部变量表是食材,操作数栈是做法步骤

===》2022.04.17虚拟机栈中结构初理解

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/96263.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!