javaEE-8.JVM(八股文系列)

目录

一.简介

二.JVM中的内存划分

JVM的内存划分图:

堆区:​编辑

栈区:​编辑

程序计数器:​编辑

元数据区:​编辑

经典笔试题:

三,JVM的类加载机制

1.加载:

2.验证:

3.准备:

4.解析:

5.初始化:

双亲委派模型

概念:

 JVM的类加载器 默认有三种:

双亲委派模型的工作流程:

四.JVM的垃圾回收机制(GC)

 垃圾回收步骤:

1.识别出垃圾

1)引用计数

2)可达性分析

2.把标记为垃圾的对象的内存空间进行释放

1)标记-清除:

2)复制算法

3)标记整理

分带回收


一.简介

JVM : java Virtual Machine 的简称,意为Java虚拟机。

java的执行流程是:先通过javac 将.java文件转为.class(字节码文件)文件,之后在某个平台执行;然后 通过JVM 将.class文件转换为CPU能识别的机器指令。

因此,编写一个java程序,只需要发布.class文件就行了。JVM拿到.class文件,就知道该如何转换了.

二.JVM中的内存划分

JVM也相当于一个进程,在启动一个java程序后,需要个JVM分配资源空间.

JVM从系统中申请的内存,会根据java程序中不同的使用途径,为其分配空间.这就是内存划分.

JVM会将申请到的空间划分成几个区域,每个区域有不同的功能,

JVM的内存划分图:

堆区:

存放的是代码中new出来的对象,对象中的非静态成员也在堆区.

栈区:

包含了一些方法调用关系和局部变量.

由本地方法栈和虚拟机栈组成,本地方法栈是JVM内部,是由C++写的;虚拟机栈保存了一些java的方法调用和局部变量。

平时所说的栈区,指的是虚拟机栈,

程序计数器

这个区域比较小,专门用来保存下一条要执行的java指令的地址。

元数据区:

包含了一些辅助性质的,描述性质的属性。元数据区也叫做方法区。

元数据是计算机中的一个常见术语(Meta data)。

对于硬盘来说,不仅要存储文件的数据本体,还要存储一些辅助信息,像文件的大小,文件的位置,文件的使用权限,文件的拥有者....这些都称为“元数据”。

一个程序中,有哪些类,有哪些方法,每个方法中有哪些指令,....这些信息都会保存在JVM的元数据区.

对于堆区和元数据区,整个进程中只有一份;而对于栈区和程序计数区,在内存中是有很多份的.

经典笔试题:

class Test {private int n;private static int m;
}
public static void main(String args[]){Test t = new Test();
}

问: n,m,t 都在哪块JVM的哪个内存区域中?

n属于局部变量,在作用域中生效,出作用域就销毁了,存在栈区.

m:属于静态变量,存在元数据区。

t:是new出来了一个Test对象,t中保存的是Test的地址,属于局部变量,保存在栈区;而Test对象则保存在堆区.

区分变量在内存的哪个区域上,最重要的就是确定该变量的"形态",是 局部变量/成员变量/静态变量....

三,JVM的类加载机制

类加载指的是JVM把.class文件从硬盘读取到内存,进行一系列的校验解析的过程.转换成类对象的过程.

类加载过程大致分为五步:

1.加载:

把.class文件找到并打开,读取到文件中的内容.

2.验证:

需要确定当前读到的文件是合法的.class文件(字节码文件).否则若读到错误的文件,后面的工作就白费了.

具体的验证依据是在java的虚拟机规范中,有明确的格式说明:

左面这一列是类型,右面这一列是名字.

:

也叫做:magic number 魔幻数字,用来标识二进制文件中的格式的类型.

:

这两个都是版本号,u4 是主版本,u2 是次版本.属于JVM内部的版本,JVM会验证.class文件的版本号是否符合要求.

一般来说 高版本的JVM可以运行低版本的.class文件,反之不行.

3.准备:

为类对象申请内存空间.此时申请到的内存空间都为默认值 为全0的.

4.解析:

主要是针对类中的字符串常量进行处理.

将常量池中的 符号引用 替换为 直接引用 的过程,也就是初始化常量的过程.

我们知道,在.class文件中,是不存在地址的,而对于创建的字符串常量,变量中保存的是常量的地址,这又是怎样记录的呢?

class Test{private String s="hello";
}

这个hello在.class文件中,是否会保存呢?

当然是要保存的,只不过s中保存的是一个字符串常亮的"偏移量".

在文件中,不存在地址这样的概念,地址是内存的地址,而文件是在硬盘中的.

为了保存字符串常来那个,可以存储一个"偏移量"的概念, 这里的偏移量就认为是符号引用.

之后,把.class文件加载到内存中,就有地址了,s中的值就能根据偏移量来转换为真正地址了,也就是直接引用.

5.初始化:

针对类对象,完成后续的初始化操作.

执行静态代码块,构造方法,还可能触发父类加载.....

双亲委派模型

在类加载过程的第一步:加载环节中使用 双亲委派模型 描述如何查找.class文件的策略.

JVM在进行类加载的时候,有一个专门的模块,称为"类加载器".(ClassLoader)

概念:

双亲委派模型: 如果一个类加载器收到一个类加载的请求,他首先不会自己加载该类,而是将这个类委派给父类加载器,让父类加载器去完成对类的加载.每层次的类加载器都是这样委派,最终所有的加载请求都会到达 最顶层的类加载器,直到当父类加载器反馈自己无法完成这个类加载请求时,子类加载器就会尝试自己完成加载.

 JVM的类加载器 默认有三种:

BootstrapClassLoader: 负责查找标准库目录.

ExtensionClassLoader: 负责查找扩展库目录.

ApplicationClassLoader: 负责查找当前项目的代码目录,以及第三方库.

 这三个类加载器存在父子类(二叉树关系)关系.

ApplicationClassLoader的父类是ExtensionClassLoader;

ExtensionClassLoader的父类是BootstrapClassLoader,BootstrapClassLoader属于顶层父类。

双亲委派模型的工作流程:

1.类加载任务先从ApplicationClassLoader为入口,开始工作;

2.ApplicationClassLoader自己不会立即搜索自己负责的目录,会将搜索的任务向上传递给父类;

3.代码进入ExtensionClassLoader的范畴,同样,ExtensionClassLoader 也不是立即搜索自己负责的目录,继续将搜索的任务向父类传递;

4.代码进入BootstrapClassLoader的范畴,由于BootstrapClassLoader是顶级父类了,就会真正进行负责搜索目录(标准库目录),尝试在标准库目录中找到符合要求的.Class文件;

5.若是找到了,就会进入打开文件,读文件流程了,此时类加载步骤就结束了;若是没有找到,就会返回到子类的类加载器中,继续尝试加载。

6.若是在ExtensionClassLoader类加载器中找到符合要求的.Class文件,此时类加载步骤就结束了;若还未找到,就会返回给子类加载器ApplicationClassLoader继续尝试加载.

7.若在ApplicationClassLoader类加载器中搜索到了,此时类加载就结束了,就会进入后续流程;若是没有找到,就会继续向子类寻找,由于ApplicationClassLoader是底层了,就表示类加载失败了.

这一系列的列加载机制,目的是为了保证这几个类加载器的优先级顺序.

这个类加载器是系统默认的类加载机制,也可以自己实现类加载机制,可以与默认机制不同.

四.JVM的垃圾回收机制(GC)

垃圾回收指的是让程序自动回收内存,JVM中的内存分为好几种,要回收的是堆区的内存;

元数据区和程序计数区的内存不需要回收,栈区中存放的都是局部变量申请的内存,在代码结束后,会自动销毁(属于栈区自己的特点,和垃圾回收没有关系)。

回收内存其实就是回收对象,垃圾回收时,将堆区上的若干个对象释放掉。

堆区内存根据垃圾回收,又分为三类区间:

 垃圾回收步骤:

1.识别出垃圾

要判定哪些对象是垃圾,哪些对象不是垃圾。就是判断该对象是否还需要使用。

在java中,使用对象,一定是通过引用指向使用对象的方式使用,若该对象没有引用指向,则表示该对象不再被使用,就可以进行垃圾回收了。

class Test{
....
}
void func(){
Test t = new Test(); }

这个代码中,执行结束后,t属于局部变量,存在于栈区,会被直接释放掉,Test对象在执行完后,由于没有对象指向了,也就属于垃圾了,就会被垃圾回收。

对于一些更复杂的代码,判定过程也就更加复杂。

Test t1 = new Test();
Test t2 = t1;
Test t3 = t2;
Test t4=t3;
....

很多引用都指向了同一个对象Test,只有当所用的引用都结束了,才能释放Test对象,但每个引用的生命周期又不一样,就很难判断了。

于是又设计一些方法来记录对象的引用:

1)引用计数

给每个对象再分配一个额外的空间,保存当前对象引用个数,当有一个引用指向了该对象,引用计数就+1,一个引用结束后,引用计数就-1.

此时的垃圾回收机制就是:有一个专门的扫描线程,取获取每个对象的引用计数的情况,当引用计数为0时,就表示该对象没有引用指向了,不再使用了,也就可以释放了。

class Test {....
}
void func() {
Test t1 = new Test();
Test t2 = t1;
}

这个代码的内存分配:

引用计数 存在的问题:

1)耗费额外的空间

引用计数需要耗费一个额外的空间,若对象本身占用的内存就比较小,总的对象数目有很多,那么总的消耗空间就会非常多。

2)可能出现“循环引用问题”:

class Test{Test t;
}
Test t1 = new Test();
Test t2 = new Test();
t1.t = t2;
t2.t = t1;
t1 = null;
t2 = null;

当t1和t2还未被置为null的时候,此时的内存是这样的情况:

 当t1和t2都被置为null后,t1,t2内存被释放,但Test对象中的t还未被释放:

此时,Test的引用计数还都不是0,不能被GC回收,但又无法使用,就产生了循环引用问题,这种情况下的引用计数就无法被正常使用了。

引用计数 这种思想 并未在java中使用,在别的语言的垃圾回收机制中有使用到。

2)可达性分析

(JVM的垃圾回收机制 识别垃圾 采用的是这种思想)

可达性分析本质上是采用“时间”换“空间”的方法。

相较于 引用计数,可达性分析要消耗更多的时间去“遍历”,不会存在上面 引用计数 中的问题。

可达性分析:一个java代码中,会定义很多变量,从这些变量为起点,向下“遍历”:从这些变量中持有的引用类型的成员,再向下遍历,所有能被访问到的对象,一定不是垃圾了,而未被访问到的对象,就是垃圾了,要被就行回收。

JVM自身有扫描线程,会不停地扫描代码,看是否有对象无法被遍历到;JVM本身是知道一共有多少个对象的。

class Node{char root;Node left;Node right;
}
Node BuildNode{
Node a = new Node();
Node b = new Node();
Node c = new Node();
Node d = new Node();
Node e = new Node();
Node f = new Node();
Node g = new Node();
a.left = b;
a.right = c;
b.left = d;
b.right = e;
c.right = f;
e.left = g;
}
public static void main(String args[]){
Node root = BuildNode();
}

代码中的树是这个样子,

在这个代码中,虽然只有一个root这样的引用,但实际上有7个对象都是可达的,

若代码中出现: c.right=null;此时f就是不可达的,f就属于垃圾了.要进行回收.

若a=null;那么整个二叉树都是不可达的了.都要进行垃圾回收.

2.把标记为垃圾的对象的内存空间进行释放

具体的释放方法有三种.

1)标记-清除:

把标记为垃圾的对象,直接进行释放。(最直接的方法)

这种做法可能会产生大量的“内存碎片”,会存在很多小的,离散的可用空间。

可能导致后续申请内存空间失败,申请内存空间都是一次申请一个连续的内存空间,此时可能内存中总得空间是够当前要申请的内存空间的,但内有连续的内存空间够分配,就可能申请失败。

2)复制算法

先把申请的内存分成两部分,申请内存时都在一半的内存中创建;进行释放时,把不是垃圾的对象的内存复制到另一半内存中,然后把带有垃圾的半个内存全部释放掉。

将不是垃圾的对象都复制到另半个内存中:

再把左半部分的内存中的对象都释放掉

这个方法也存在一些问题:

1、每次释放内存,要释放一半的内存,总的可用内存减少了很多。

2、若引用的对象很多,对对象的复制也要消费很大的开销。

3)标记整理

类似于顺序表中,删除元素的方法。

遍历整个内存,若有遍历到的对象标记为垃圾,不用管,后面遍历到不是垃圾的对象内存就覆盖垃圾的内存空间,这样既不会存在“内存碎片”,又不会一次释放很多的内存。

这个方法的缺点是搬运内存会有很大的开销。

上面的方法都有一定的缺点和问题,因此,JVM并没有直接使用上面的方法,而是对上面的方法思想,采用了一个·“综合性”方案:“分带回收”。

分带回收

依据不同种类的对象,采用不同的回收方式。

JVM引入了一个概念:年龄。

JVM的扫描线程会不断的扫描内存,若该对象是可达的,年龄就+1;

JVM根据对象年龄的不同,将内存分为两个区域:新生代 和 老年代。

新生代中又划分了三个大小不等的区域:其中一个大的区域叫伊甸区 和 两个小的等大的生存区(幸存区)。

回收过程:

1.当创建出一个对象后,该对象会先被创建到伊甸区,(伊甸区的对象大多都被第一轮GC扫描到了,就会被回收掉)

2.第一轮GC后,少数存活的对象通过复制算法被送到其中一个生存区,扫描还在继续,生存区中被标记的对象就会被清除掉,极少数的生存区的对象会再次通过复制算法,从一个生存区复制到另一个生存区,这样循环扫描复制,每经过一轮GC的扫描,年龄就会+1.

3.当这个对象在生存区经过了若干轮扫描,年龄已经很大了,说明这个对象的生命周期可能很长,就将这个对象拷贝到老年代,老年代中的对象经过GC扫描的频率要比新生代低很多。

4.当扫描老年代中的对象,也被标记为垃圾了,也会进行释放。

这个分带回收就类似于找工作一样:

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

物业管理系统源码提升社区智能化管理效率与用户体验

内容概要 物业管理系统源码是一种针对社区管理需求而设计的软件解决方案,通过先进的智能化技术,使物业管理变得更加高效和人性化。随着城市化进程的加快,社区的管理复杂性不断增加,而这一系统的推出恰好为物业公司提供了极大的便…

读算法简史:从美索不达米亚到人工智能时代05天气预报

1. 天气预报 1.1. 自古以来,生命就与变幻莫测的天气息息相关 1.1.1. 在很多情况下,只要能提前一天得知天气情况,人类就可以避免灭顶之灾 1.1.2. 公元前2000年,准确预测天气是众神的特权 1.2. 大约在公元前650年,巴…

整形的存储形式和浮点型在计算机中的存储形式

在计算机科学的底层世界里,数据存储是基石般的存在。不同数据类型,如整形与浮点型,其存储方式犹如独特的密码,隐藏着计算机高效运行的秘密。理解它们,是深入掌握编程与计算机原理的关键。 一、整形的存储形式 原码、反…

Python网络自动化运维---批量登录设备

文章目录 目录 文章目录 前言 实验准备 一.批量登录 IP 连续的设备 1.1.1 实验代码 1.1.2 代码分段分解 1.1.3 实验结果验证 二.批量登录 IP 不连续的设备 2.2.1 实验代码 2.2.2 代码分段分解 2.2.3 实验结果验证 前言 在生产环境中,我们通常需要登录多个设备…

selenium记录Spiderbuf例题C03

防止自己遗忘,故作此为记录。 鸢尾花数据集(Iris Dataset) 这道题牵扯到JS动态加载。 步骤: (1)进入例题,需要找到按钮规律。 flip_xpath: str r"//li/a[onclickgetIrisData({});]" (2&…

【C++篇】位图与布隆过滤器

目录 一,位图 1.1,位图的概念 1.2,位图的设计与实现 1.5,位图的应用举例 1.4,位图常用应用场景 二,布隆过滤器 2.1,定义: 2.2,布隆过滤器的实现 2.3, 应…

基于SpringBoot的新闻资讯系统的设计与实现(源码+SQL脚本+LW+部署讲解等)

专注于大学生项目实战开发,讲解,毕业答疑辅导,欢迎高校老师/同行前辈交流合作✌。 技术范围:SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容:…

Spring Boot 2 快速教程:WebFlux处理流程(五)

WebFlux请求处理流程 下面是spring mvc的请求处理流程 具体步骤: 第一步:发起请求到前端控制器(DispatcherServlet) 第二步:前端控制器请求HandlerMapping查找 Handler (可以根据xml配置、注解进行查找) 匹配条件包括…

C基础寒假练习(2)

一、输出3-100以内的完美数&#xff0c;(完美数&#xff1a;因子和(因子不包含自身)数本身 #include <stdio.h>// 函数声明 int isPerfectNumber(int num);int main() {printf("3-100以内的完美数有:\n");for (int i 3; i < 100; i){if (isPerfectNumber…

react-bn-面试

1.主要内容 工作台待办 实现思路&#xff1a; 1&#xff0c;待办list由后端返回&#xff0c;固定需要的字段有id(查详细)、type(本条待办的类型)&#xff0c;还可能需要时间&#xff0c;状态等 2&#xff0c;一个集中处理待办中转路由页&#xff0c;所有待办都跳转到这个页面…

GRN前沿:利用DigNet从scRNA-seq数据中生成基于扩散的基因调控网络

1.论文原名&#xff1a;Diffusion-based generation of gene regulatory network from scRNA-seq data with DigNet 2.出版时间&#xff1a;2024.12.18 3.doi: 10.1101/gr.279551.124 摘要&#xff1a; 基因调控网络&#xff08;GRN&#xff09;在细胞内基因的身份和功能之间…

AnswerRocket:通过 AI 辅助简化分析

AnswerRocket是一家专注于人工智能驱动数据分析和商业智能的领先企业&#xff0c;其核心产品是一款增强型分析平台&#xff0c;旨在通过自然语言处理&#xff08;NLP&#xff09;、机器学习&#xff08;ML&#xff09;和生成式AI技术&#xff0c;简化复杂数据的分析过程&#x…

小程序设计和开发:如何研究同类型小程序的优点和不足。

一、确定研究目标和范围 明确研究目的 在开始研究同类型小程序之前&#xff0c;首先需要明确研究的目的。是为了改进自己的小程序设计和开发&#xff0c;还是为了了解市场趋势和用户需求&#xff1f;不同的研究目的会影响研究的方法和重点。例如&#xff0c;如果研究目的是为了…

我的AI工具箱Tauri版-ZoomImageSDXL全图超清放大TILE+SDXL

本教程基于自研的AI工具箱Tauri版进行ComfyUI工作流ZoomImageSDXL全图超清放大TILESDXL。 ZoomImageSDXL全图超清放大TILESDXL 借助ControlNet的Tile技术与SDXL大模型&#xff0c;该工具能够在放大图像的同时&#xff0c;精准还原细节和纹理&#xff0c;确保输出效果既清晰锐利…

Java设计模式:行为型模式→状态模式

Java 状态模式详解 1. 定义 状态模式&#xff08;State Pattern&#xff09;是一种行为型设计模式&#xff0c;它允许对象在内部状态改变时改变其行为。状态模式通过将状态需要的行为封装在不同的状态类中&#xff0c;实现对象行为的动态改变。该模式的核心思想是分离不同状态…

蓝桥与力扣刷题(234 回文链表)

题目&#xff1a;给你一个单链表的头节点 head &#xff0c;请你判断该链表是否为回文链表。如果是&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 示例 1&#xff1a; 输入&#xff1a;head [1,2,2,1] 输出&#xff1a;true示例 2&#xff1a; 输入&…

【面经】字节南京一面部分题目记录

南京字节一面题&#xff0c;可能因为项目不太匹配&#xff0c;全程八股比较多&#xff0c;也有两道手撕代码题&#xff0c;强度还是有的。为了方便大家学习&#xff0c;大部分答案由GPT整理&#xff0c;有些题给出了我认为回答比较好的博客链接。 文章目录 一、python2 和 pyth…

【C语言篇】“三子棋”

一、游戏介绍 三子棋&#xff0c;英文名为 Tic - Tac - Toe&#xff0c;是一款简单而经典的棋类游戏。游戏在一个 33 的棋盘上进行&#xff0c;两名玩家轮流在棋盘的空位上放置自己的棋子&#xff08;通常用 * 和 # 表示&#xff09;&#xff0c;率先在横、竖或斜方向上连成三个…

vscode软件操作界面UI布局@各个功能区域划分及其名称称呼

文章目录 abstract检查用户界面的主要区域官方文档关于UI的介绍 abstract 检查 Visual Studio Code 用户界面 - Training | Microsoft Learn 本质上&#xff0c;Visual Studio Code 是一个代码编辑器&#xff0c;其用户界面和布局与许多其他代码编辑器相似。 界面左侧是用于访…

【B站保姆级视频教程:Jetson配置YOLOv11环境(六)PyTorchTorchvision安装】

Jetson配置YOLOv11环境&#xff08;6&#xff09;PyTorch&Torchvision安装 文章目录 1. 安装PyTorch1.1安装依赖项1.2 下载torch wheel 安装包1.3 安装 2. 安装torchvisiion2.1 安装依赖2.2 编译安装torchvision2.2.1 Torchvisiion版本选择2.2.2 下载torchvisiion到Downloa…