2.22JVM

news2024/11/25 16:27:59

一.学习目标

1)JVM内存区域划分

2)JVM的类加载机制

3)JVM的垃圾回收

1.JVM执行流程

程序在执行之前先要把Java代码转换为字节码(.class),JVM首先需要通过一定的方式类加载器把文件加载到运行时数据区,而字节码文件是JVM的一套指令集规范,并不能直接交给底层操作系统去执行,因此需要特定的命令解析器 执行引擎,将字节码翻译成底层系统指令再交给CPU去执行,而这个过程需要其他语言的接口

本地接口库实现整个程序的功能

口来实现整个程序的功能,这就是四个部分的职责与功能

二.JVM的内存区域划分

(45条消息) JAVA内存模型与JVM内存模型的区别_Tiantian_126的博客-CSDN博客_java内存模型和jvm内存模型的区别

JVM运行时数据区域也叫内存布局,与java内存模型完全不同

1.程序计数器(线程私有)

内存中最小的区域

保存了下一条指令的地址在哪里

指令也就是字节码文件

程序要想运行,JVM需要把字节码文件加载起来放到内存上

程序就会一条一条把指令从内存取出来,放到CPU执行

也就要随时记住 ,当前执行到哪一条了

因为CPU是并发式的执行程序的,

CPU要同时运行所有的进程

而操作系统是以线程为单位进行调度执行,每个线程都得记录自己的执行位置

所以每个线程都有一个程序计数器

2.栈(线程私有)

放进了局部变量和方法调用信息

每个线程都独有一份

举例

B用完返回调用B方法在A调用的位置

每一个方法都有自己的栈帧

错误注意!

3.堆(线程共享)

堆里面分为两个区域:新生代和老生代,新生代放新建的对象,当经过一定 GC 次数之后还存活的对象会放入老生代。新生代还有 3 个区域:一个 Endn + 两个 Survivor(S0/S1)。

一个进程用一个堆

多个线程共用一个堆

也是内存中空间最大的区域

4.方法区(线程私有)

方法区中,放入的是"类对象"

.java - >.class(二进制字节码)

.class会被加载到内存中,也就被JVM构成了类对象(加载的过程就称为"类加载")

这里的类对象,就是放到方法区中

类对象就描述了这个类长什么样

类的名字,成员,方法,成员的名字与类型,是public/private.每个方法叫什么名字,是什么类型,public/private.方法里面的指令

还有一个重要动东西(静态成员)

static修饰的成员 是"类属性"

普通的成员 "实例属性"

三.类加载

在设计一个运行环境的时候一个重要核心功能

1.类加载的目标

把.class文件加载到内存中,构建成类对象

分为三个过程

loading linking initializing

1)Loading 环节

先找到对应的.class文件,打开并读取.class文件,同时初步生成一个大概的类对象

Loading最关键的一个环节,就是读取解析class文件

并把读取解析得到的信息初步填写到类对象中

2)Linking 环节

建立多个实体之间的联系

2.1 Verification 校验

主要是验证读到的内容是不是和规范的规定的格式是否完全匹配

如果发现读到的数据格式不符合规范,就会类加载失败,并抛出一个异常

2.2Preparation 准备

准备阶段正式为类中定义的变量(即静态变量,被static修饰的变量)

分配内存并设置变量初始值阶段

就是

①给静态变量分配内存

②并设置到0值

③给他在内存上设置编号为了最后一个阶段做准备

2.3Resolution 解析

Java虚拟机将常量池的符号引用替换为直接引用的过程,也就是初始化常量的过程

.class文件,常量是集中放置的,每个常量都有一个编号

就是准备阶段给的..class文件的结构体里初始情况下只是记录了编号赋值0

resolution阶段需要根据编号找到对应内容填充到类对象中

3) Initializing 初始化

真正对类对象进行初始化,尤其针对静态成员

2.经典面试题

总结

1.类加载阶段会进行静态代码块的执行

要想创建实例,势必要先进行类加载.

2.静态代码块只是在类加载阶段执行一次

3.构造方法和构造代码块,每次实例化都会进行,

构造代码块在构造方法前面

4.父类执行在前,子类执行在后.

四.双亲委派模型

类加载的一个环节-loading阶段

JVM的类加载器 如何根据类的全限定名(java.lang.String)找到.class文件的过程

1.类加载器

JVM提供了专门的对象,叫类加载器,负责进行类加载

找文件的过程也是通过类加载器来负责的

.class文件可能放置的位置有很多,有的要放到jdk目录里,有的要放到项目目录里

还有在其他特定位置

因此,JVM里面提供了多个类加载器,每个类加载器负责了一个片区

默认的类加载器 主要有三个

1) BootStrapClassLoader

负责加载标准库中的类(String,ArrayList.Random,Scanner)

2)ExtensionClassLoader

负载加载JDK扩展的类 很少用到

3) ApplicationClassLoader

负责加载到当前项目目录中的类

程序员还可以自定义类加载器,来加载其他目录的类

例如Tomcat就自定义了类加载器,用来专门加载webapps里面的.class

双亲委派机制就描述了这个找目录的过程中,上述的类加载器如何配合

2.工作机制

1)考虑,加载java.lang.String

a.程序启动,先进入ApplicationClassLoader类加载器

b.ApplicationClassLoader就会先插,它的父类加载器是否已经加载过,如果没有

就调用父类加载器 ExtensionClassLoader

c.ExtensionClassLoader也会检查,它的父加载其是否加载过了.如果没有 就调用

它的父类加载器,BootStrapClassLoader

d.BootStrapClassLoader也会检查,它的父类加载器是否加载过,自己有没有父亲,

于是自己扫描自己负责的目录

e.java.lang.String这个类能在标准库找到,直接由BootStrapClassLoader负责后续的加载过程

2)考虑加载自己写的Test类

a.程序启动,先进入ApplicationClassLoader类加载器

b.ApplicationClassLoader就会先插,它的父类加载器是否已经加载过,如果没有

就调用父类加载器 ExtensionClassLoader

c.ExtensionClassLoader也会检查,它的父加载其是否加载过了.如果没有 就调用

它的父类加载器,BootStrapClassLoader

d.BootStrapClassLoader也会检查,它的父类加载器是否加载过,自己有没有父亲,

于是自己扫描自己负责的目录,没有找到,就回到子加载器ExtensionClassLoader

e.ExtensionClassLoader也扫描自己负责的目录,也没扫描到,

回到子加载器ApplicationClassLoader继续扫描

f.ApplicationClassLoader也扫描自己负责的目录,能找到Test类,于是进行后续加载,查找目录的环节结束

3.原因

一旦程序员自己写的类,与标准库的类,全限定类名重复了,也能够顺利加载到标准库的类

五.JVM的垃圾回收机制

1.概述

写代码的时候,需要经常申请内存

创建变量

new 对象

加载类..

申请内存的时机,一般都有明确,

需要保存某个某些数据,就需要申请内存

释放内存的时期,则不是那么清楚

内存的释放,早了也不行,完了也不行,能够恰到好处

对于c语言,需要程序员自己释放内存

所以会经常出现一个问题->内存泄露

对于c++ 提出了一个智能指针,一定程度的降低内存泄露的可能性

垃圾回收,本质上靠运行时候环境,额外做了很多工作,来完成自动释放内存的操作

2.劣势

1.消耗额外的资源

2.可能会影响到程序的流畅运行----垃圾回收经常会引入STW问题

(Stop T和World)

c++的核心原则是安身立命之本

1.与c语言兼容,也能够和各种硬件各种操作系统做到最大化的兼容

2,追求性能的机制

3.回收的内容

内存有很多种

1.程序计数器--固定大小,不涉及到释放,也就不需要GC

2,栈-----函数执行完毕,对应的栈帧就自动释放,也不需要GC

3.堆-----最需要GC.因为代码最大的内存就在堆上

4,方法区-====是类对象,类加载来的,进行"类卸载"就需要释放内存,

卸载操作其实是一个非常低频的操作

4.堆

垃圾回收的基本单位是"对象:,而不是"字节"

5.垃圾回收的过程

两个大的阶段

1.找垃圾/判定垃圾

2.释放垃圾

1)找垃圾/判定垃圾

核心就是确定这个对象未来是否还会使用,

没有引用指向,就表示不使用了

当下主流的思路,有两种方法

1.基于引用计数(是Python采取的方法)

针对每个对象,都会额外引入一小块内存,保存这个对象有多少个引用指向

这个内存不再使用,就释放了

引用计数为0,就不再使用了

通过引用来决定对象的生死

引用计数简单可靠高效但是有缺点

1.空间利用率低,每个new的对象都得搭配个计数器,(计数器假设四个字节)

假如对象本身很大,多出来4个字节,那没事,但是如果对象很小,空间就浪费了

2.循环引用的问题

1.

2.

t1.t引用指向t2

t2.t引用指向t1

3.

此时此刻,两个对象的引用计数不为0.所以无法释放,但是由于引用长在彼此的身上所以外界代码无法访问

此时这两个对象就被孤立了,既不能使用,也不能释放

这就是内存泄露的问题

2.基于可达性分析(java采取的方案)

通过额外的线程,定期对整个内存空间的对象进行扫描

有些起始位置(GCRoots),会类似于深度优先遍历一样,把可以访问到的对象都标记一遍

GCRoots分为三类

1)栈上的局部变量

2)常量池中的引用指向的对象

3)方法区中的静态成员指向的对象

带有标记的对象就是可达对象,没有标记的对象,就是不可达 也就是垃圾

可达性分析的优点,就是克服了引用计数的两个缺点:1.空间利用率低 2.循环利用

可达性分析的缺点:系统开销大,遍历一次比较慢

2)回收垃圾

三种策略,标记-清除,2.复制算法,3.标记整理

1.标记-清除

标记就是可达性分析的过程

清除就是直接释放内存

如果直接释放,但是被释放的内存是离散的,不是连续的,分散开,带来的问题就是"内存碎片"

2.复制算法

第一步把不是垃圾的拷贝到另一半

第二步,这一半整体释放

此时就可以解决内存碎片的问题

问题:

1.内存空间利用率低

2.如果要保留的对象多,要释放的对象少,此时复制开销就很大

3.标记-整理

把要的往不要的搬运

这个方法空间利用率高但是没有解绝复制高

6.分代回收

上述方法,虽然都能解决问题,但是都有缺陷,实际上JVM的实现,

会把多组方案结合使用

针对对象进行分类(根据对象的年龄分类)

年龄----一个对象熬过一轮GC的扫描 就长了一岁

1.刚创建出来的对象,就放在伊甸区

2.如果伊甸区的对象熬过一轮GC扫描,就会被拷贝到幸存区(复制算法)

3.在后续的几轮GC中,幸存区的对象就会在两个幸存区之间来回拷贝(复制算法)

每一轮都会淘汰一波幸存者

4,在持续若干轮后,进入老年代

老年代的清除是(标记-整理)

5.特殊情况

大对象,占有内存多的对象直接进入老年代

因为大对象拷贝开销大,不适合使用复制算法

7.垃圾回收器

1) 历史遗留

2)目前主流

CMS收集器

G1收集器

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/365283.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【11-JVM面试专题-说说你知道的垃圾回收算法?垃圾回收器你知道吗?CMS、G1和ZGC垃圾回收器你有过了解吗?】

JVM面试专题-说说你知道的垃圾回收算法?垃圾回收器你知道吗?CMS、G1和ZGC垃圾回收器你有过了解吗? JVM面试专题-说说你知道的垃圾回收算法?垃圾回收器你知道吗?CMS、G1和ZGC垃圾回收器你有过了解吗?你掌握的…

Wincc Flexible smart V4触摸屏软件中批量导入PLC变量的具体方法示例(无需单个添加)

Wincc Flexible smart V4触摸屏软件中批量导入PLC变量的具体方法示例(无需单个添加) 具体操作步骤可参考以下例子中的内容: 打开STEP7-MicroWin smart软件,编辑自己的PLC程序(这里以一个简单的启保停程序为例), 如下图所示,打开Wincc Flexible smart V4触摸屏软件,新建…

双指针 (C/C++)

1. 双指针 双指针算法的核心思想:将暴力解法的时间复杂度,通常是O(N*N),通过某种特殊的性质优化到O(N)。 做题思路:先想想暴力解法的思路,然后分析这道题的特殊性质,一般是单调性。然后得出双指针算法的思路…

微信协议网页版微信协议解析

最近在做个微信机器人,所以研究了网页版的微信协议及相关接口,在这里简单总结一下。从表面上看,对于网页版微信我们的使用流程是这样的:很简单,只有四步,但如果细化到内里细节的话,上面这简单四…

一文带你快速入门zabbix6.0的日常操作

文章目录前言一. zabbix基本操作入门1.1 登录和配置用户1.1.1 登录zabbix1.1.2 防爆力破解机制1.1.3 创建用户1.1.4 创建报警媒介1.1.5 设置 权限选项卡1.1.6 设置用户的访问主机权限1.2 新建主机1.2.1 添加主机1.2.2 关于添加的信息注释1.3 新增监控项1.3.1 添加监控项1.3.2 配…

若依系统如何集成qq邮件发送【超详细,建议收藏】

若依系统的部署博主就不在这儿阐述了,默认大家的电脑已经部署好了若依系统,这里直接开始集成邮件系统,首先我们得需要对qq邮箱进行配置;一套学不会你来打我😀; 一、开启我们的qq邮箱发送邮件的配置 1、先进…

Qt音视频开发16-通用悬浮按钮工具栏的设计

一、前言 通用悬浮按钮工具栏这个功能经过了好几个版本的迭代,一开始设计的时候是写在视频控件widget窗体中,当时功能简单就放一排按钮在顶部悬浮widget中就好,随着用户需求的变化,用户需要自定义悬浮条的要求越发强烈&#xff0…

K_A12_031 基于STM32等单片机驱动TEMT6000环境光传感器 串口与OLED0.96双显示

K_A12_031 基于STM32等单片机驱动TEMT6000环境光传感器 串口与OLED0.96双显示一、资源说明二、基本参数参数引脚说明三、驱动说明IIC地址/采集通道选择/时序对应程序:四、部分代码说明1、接线引脚定义1.1、STC89C52RCTEMT6000环境光传感器模块1.2、STM32F103C8T6TEMT6000环境光…

ZCMU--5009: 龙虎斗

轩轩和开开正在玩一款叫《龙虎斗》的游戏,游戏的棋盘是一条线段,线段上有n个兵营(自左至右编号1~n),相邻编号的兵营之间相隔1厘米,即棋盘为长度为n-1厘米的线段。i号兵营里有ci位工兵。 下面图1为n 6的示例: 轩轩在左侧&#xf…

如何通过IP找到地址?

在我们印象中,我们都知道可以通过 IP 地址找到某个人。但当我们细想一下,我们会发现其实 IP 地址与地理位置并不是直接相关的。那我们到底是如何通过 IP 地址找到地址的呢?答案是:通过自治系统(Autonomous System&…

大势前瞻!文旅还是短视频,你弯道超车风口在这了

三年前,新冠疫情的影响波及整个各行各业行业,互联网寒冬,房地产崩盘,教培团灭,在这样的背景下,行业都进入了发展“冰雪期”。老话说大疫后必有大变,如今风雪融化,万物复苏&#xff0…

day01_HTML常识

基础概念铺垫 认识网页 网页的组成:文字、图片、音频、视频、超链接一系列元素网页的本质:程序员写的代码通过浏览器转化(解析和渲染)成用户看到的网页网页是由网页元素组成的 , 这些元素是利用html标签描述出来&…

面试攻略,Java 基础面试 100 问(十八)

JAVA IO 包 JAVA NIO NIO 主要有三大核心部分:Channel(通道),Buffer(缓冲区), Selector。 传统 IO 基于字节流和字 符流进行操作,而 NIO 基于 Channel 和 Buffer(缓冲区)进行操作,数据总是从通道读取到缓冲区 中,或者…

不可替代的测试人:一文解释探索性测试是什么

剧本式测试 随着软件技术的发展,软件开发过程中对软件测试的需求越来越庞大,从原来单纯的寻找软件缺陷,到后来的学习软件、挖掘软件中存在的缺陷、评估软件可用性、性能等等方面,软件测试发挥着重要作用。 考虑到软件测试如此的…

视频流截取保存到本地路径(打包jar包CMD运行)

需求:现在有一批https的监控视频流URL,需要对视频流进行每三秒截屏一次,并保存到本地路径,png格式,以当前时间命名。代码:import org.bytedeco.javacv.FFmpegFrameGrabber; import org.bytedeco.javacv.Fra…

微信小程序登录

小程序登录 | 微信开放文档 (qq.com)https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/login.html 静默登录 首先需要在微信开发者工具中获取code(wx.login(Object object) | 微信开放文档 (qq.com)) 前端处理获取code其次:需要appid,se…

PyQt5数据库开发2 5.1 QSqlQueryModel

目录 一、Qt窗体设计 1. 新建Qt项目 2. 拷贝4-3的部分组件过来 3. 添加资源文件 4. 创建Action 5. 添加工具栏 6. 创建菜单项 7. 关闭Action的实现 8. 调整布局 8.1 调整两个groupbox的布局 8.3 为窗体设置全局布局 二、代码拷贝和删除 1. 新建项目目录 2. 编译…

游戏化销售管理是什么?使用CRM系统进行有什么用?

对于企业销售来说,高薪酬也伴随着更高的压力与挑战。高强度的单一工作会让销售人员逐渐失去对工作的兴趣,导致销售状态缺少动力和激情,工作开展愈加困难。您可以通过CRM系统进行游戏化销售管理,让销售人员重新干劲满满。 游戏并不…

Matlplotlib绘图

0 建议学时 4学时 1 Matlplotlib库介绍 Matplotlib库由各种可视化类构成,内部结构复杂 受Matlab启发,matplotlib.pylot是绘制各类可视化图形的命令字库,相当于快捷方式 Matplotlib中文网:https://www.matplotlib.org.cn 安装&…