JVM
一、概述
1.特点:
1、一次编译,到处运行
2.自动内存管理
3.自动垃圾回收功能
2.跨平台性图解
3.java代码执行流程
总:高级=》汇编=》机器指令
4.通过语言之间的关系,解释上图
二、认识jvm
1、类加载器
1.1 总流程
1.2 类加载器的过程
2.1引导类加载器
c和c++实现;
为了安全只加载包名为java、javax、sun等包
2.2扩展类加载器
加载JDK安装目录下的jre/lib/ext文件
2.3系统类加载器
系统内部默认的类加载;一般我们平常都是靠他加载的
2.4用户自定义加载器
1、一般靠着上面三个就够了
2、此加载器的目的
隔离加载类、扩展加载源、防止源码泄露、修改类加载方式
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:
类加载器工作结束后,进入到运行时数据区(五大模块【本地方法栈,虚拟机栈,堆,方法区,程序计数器】),
由执行引擎来操作运行时数据区
ii:
灰色的为单独线程私有的,红色的为多个线程共享的。即:
- 线程独有:独立包括程序计数器、栈、本地方法栈
- 线程间共享:堆、堆外内存(永久代或元空间、代码缓存)
每个线程都会有一块运行时数据区吗?【每一个线程都会有一个栈帧】
2.拆分
1.程序计数器:
1.1干嘛:记录下一条指令执行的地址,由执行引擎来执行,原因cup会不停的进行任务切换
1.2怎么干:每一个线程私有的,
1.3目的:确保记录每个线程执行的地址
1.4不这么干的后果:会导致不知道执行哪一行
=====》更新2022.03.27(类加载器总结,运行时数据区概述,程序计数器)
2.虚拟机栈:
1)栈和堆的区别:栈是运行的单位,堆是储存的单位
2)每个线程都会创建一个虚拟机栈(每个线程之间的栈都是独立的)
3)虚拟机栈的生命周期和线程的生命周期一致
4)栈不存在垃圾回收,不存在GC但是存在OOM
5)栈中的内部结构
局部变量、操作数栈、动态连接、返回地址、附加信息
每个线程都会开启一个栈空间,每一个线程中的方法都会以栈帧的方式压入当前线程的栈空间中,每个栈帧中主要有以下几个部分,栈帧的大小主要由局部变量表和操作数栈决定
6)局部变量表
7)操作数栈
根据字节码指令向栈中存放数据或取出数据,
作用:存放数据中间结果,作为计算过程中变量的临时存放空间
局部变量表是食材,操作数栈是做法步骤
===》2022.04.17虚拟机栈中结构初理解
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/96263.html