[线程与网络] Java虚拟机常考面试题(线程与网络完结)

news2024/11/25 23:03:17

🌸个人主页:https://blog.csdn.net/2301_80050796?spm=1000.2115.3001.5343
🏵️热门专栏:🍕 Collection与数据结构 (92平均质量分)https://blog.csdn.net/2301_80050796/category_12621348.html?spm=1001.2014.3001.5482
🧀线程与网络(96平均质量分) https://blog.csdn.net/2301_80050796/category_12643370.html?spm=1001.2014.3001.5482
🍭MySql数据库(93平均质量分)https://blog.csdn.net/2301_80050796/category_12629890.html?spm=1001.2014.3001.5482
🍬算法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12676091.html?spm=1001.2014.3001.5482
感谢点赞与关注~~~
在这里插入图片描述

目录

  • 1. JVM内存划分
    • 1.1 堆区
    • 1.2 程序计数器
    • 1.3 元数据区
    • 1.4 Java虚拟机栈
    • 1.5 本地方法栈
    • 1.6 不同形态的变量在数据区中的存储
  • 2. JVM类加载
    • 2.1 类加载过程
    • 2.2 双亲委派模型
      • 2.2.1 什么是双亲委派模型
      • 2.2.2 工作过程
  • 3. JVM垃圾回收机制(GC)
    • 3.1 什么是GC
    • 3.2 GC的工作流程
      • 3.2.1 判断谁是垃圾
      • 3.2.2 释放对应内存(垃圾回收)

1. JVM内存划分

JVM本质上是一个Java进程,这个进程一旦跑起来,就会从操作系统中申请一大块内存空间.那么JVM接下来就要对这一大块空间进行划分,每个区域都有不同的功能.划分出来的也叫JVM运行时数据区或者也叫内存布局.
在这里插入图片描述

1.1 堆区

  • 堆区是各个数据区中最大的区域.
  • 他的作用是:程序中创建的所有对象都保存在堆中.
  • 这个区域是所有线程共享的.
  • 堆中分为两个区域,一个是新生代,一个是老年代,新生代中还有三个区域,一个是伊甸区(Eden),两个生存区(s1/s0).具体这几个区域中都存放什么样的对象,我们后面讲到垃圾回收机制的时候再说.
    在这里插入图片描述

1.2 程序计数器

  • 这个区域是数据区域中最小的区域.
  • 他的作用是:用来记录当前线程执行的行号.也就是当前要执行的下一条指令(JVM字节码)的地址,这个地址就是元数据区中的一个地址.
  • 这块区域是各个线程都有自己单独的一块,也就是线程私有的.

1.3 元数据区

  • 他的作用是:用来存储被虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码等数据.
  • 创建一个类之后产生的类对象就存储在这里.
  • 方法相关的信息也存储在这里,类中都有一些成员方法,每个方法都代表一系列"指令集合"(JVM字节码指令).
  • 这里还存储着常量池,不仅仅是string类型,也可能是数字等其他类型.
  • 这个区域是各个线程共享的.

1.4 Java虚拟机栈

  • 线程私有
  • Java虚拟机栈分为一下四部分:
    1. 局部变量表:存放了编译器可知的各种基本数据类型(8大基本数据类型)、对象引用。局部变量表所需的内存空间在编译期间完成分配,当进⼊⼀个方法时,这个方法需要在帧中分配多大的局部变量空间是完全确定的,在执行期间不会改变局部变量表大小。简单来说就是存放方法参数和局部变量
    2. 操作栈:每个方法会⽣成⼀个先进后出的操作栈。
    3. 动态链接:指向运行时常量池的⽅法引用。
    4. ⽅法返回地址:PC寄存器的地址。
      在这里插入图片描述

1.5 本地方法栈

  • 和Java虚拟机栈类似,
  • 也是线程私有的
  • 他两的区别就在于,Java虚拟机栈是给JVM使用的,而本地方法栈是给本地方法使用的.

1.6 不同形态的变量在数据区中的存储

基本原则:一个对象在哪个区域,取决于对应变量的形态.局部变量在栈上,成员变量在堆上,静态成员变量在元数据区.下面我们来举例说明:

class Test2{}
class Test{
	int a;
	Test2 t2 = new Test2();
	String s = "hello";
	static int b;
}
public static void main(String[] args){
	Test t = new Test();
}
  • main方法中的t变量在栈上,用来保存对象的首地址.(堆上的地址).
  • new Test()在堆上.是通过new创建出的一个对象.
  • new Test2()在堆上,和上一个是同理,也是通过new创建出的一个对象.
  • Test类中的成员变量都在堆上.
  • static修饰的是属于类的属性,就会出现在元数据区的类对象中.
    在这里插入图片描述

2. JVM类加载

一个Java进程要想跑起来,就要把Java先变成**.class文件.加载到内存中**,得到"类对象".这个所谓的跑起来,就是执行指令,要执行的CPU指令,都是通过字节码让JVM翻译出来的.

2.1 类加载过程

对于类加载的过程,总共分为一下几个步骤:

  1. 加载: 在硬盘上找到.class文件,读取文件内容.
  2. 连接
    • 验证:.class里的内容,是否符合要求.class文件格式的内容在官方文档中有明确的规定,把读取到的内容,往这一套标准中套入,即可判断是否符合要求
    • 准备:给类对象分配内存空间,分配之后,把这个空间里的数据先全部填充为0.
    • 解析:针对字符串常量初始化,把刚才.class文件中常量内容取出,放到元数据区.
  3. 初始化:针对类对象的初始化,其中就包含对静态成员初始化,执行初始化,执行静态代码块.注意不是针对对象的初始化.
    在这里插入图片描述

2.2 双亲委派模型

2.2.1 什么是双亲委派模型

在上述三部中,“加载"的过程中.会根据代码中"全限定类名”(包名+类名)找到对应的.class文件.在JVM加载.class文件,并找到.class文件的时候,就要用到双亲委派模型.
在JVM中包含这样一个特定的模块,叫做"类加载器",这个类负责完成后续的类加载工作.
如果⼀个类加载器收到了类加载的请求,它首先不会自己去尝试加载这个类,而是把这个请求委派给父类加载器去完成,每⼀个层次的类加载器都是如此.

2.2.2 工作过程

在这里插入图片描述

  • 这其中有三个类加载器: AppClassLoader,ExtClassLoader,BootStrapClassLoader.这三个类加载器存在父子关系,如上图所示.
    [注意] 这里的父子关系不是通过类的继承方式来表示的,而是通过类加载器中的"parent"字段指向自己的父亲.
  • 三个类加载器的作用:
    • BootStrapClassLoader:加载标准库中的类.
    • ExtClassLoader:加载JVM扩展库中的类.(各JVM厂商,在上述的标准上,对JVM进行了扩展,这样的扩展在JVM标准之外,但是在安装了JVM就有.
    • AppClassLoader:加载第三方库的类和自己写的代码的类.
  • 他们几个类加载器的工作过程就类似于望父成龙的过程.
    • 工作从AppClassLoader开始,这个类加载器并不会立即搜索第三方库相关的目录.而是把任务交给自己的父亲来进行处理.也就是ExtClassLoader.
    • 工作到了ExtClassLoader,也不会立即对自己负责的扩展库进行搜索,也是把任务交给自己的父亲来处理.
    • 工作到了BootStrapClassLoader,BootStrapClassLoader也想交给自己的父亲进行处理.但是它的parent指向null,只能自己处理.在BootStrapClassLoader负责的标准库中的路径中搜索上述的类.
    • 如果找到了,就搜索完成了,类加载器负责打开文件,读取文件等后续操作.
    • 如果没有找到,任务还是要交给儿子来处理.
    • 工作回到ExtClassLoader,搜索扩展库的类,如果找到了,搜索完成,如果没找到,继续交给儿子处理.
    • 工作回到AppClassLoader,搜索第三方库中的类和自己创建的类.

举例说明:上司与下属处理问题
下属在发现一个问题的时候,不可以自己擅自处理,需要向上级上报,如果上报给上级之后,上级觉得这个问题非常重要,上级就会亲自处理,如果问题不是很重要,上级就会对下属说:"你自己看着办吧."于是下属就有权利处理这个问题了.

  • 双亲委派模型适用于:自己写的类和标准库/扩展库冲突,JVM会确保加载的类是标准库中的类.
  • 双亲委派模型可以破坏掉,我们可以通过自己实现类加载器来破坏模型.

3. JVM垃圾回收机制(GC)

3.1 什么是GC

这是Java提供的对于内存自动回收的机制.更本质地来说,GC其实回收的是"对象",回收的是"堆上的内存".回收对象的时候,一定是一次回收一个完整的对象,不能回收半个.
在这里插入图片描述

为什么GC只回收堆上的内存,不回收其他区域的?

  • 程序计数器:不需要额外回收,他是每个线程私有的,线程销毁之后,自然就回收了.
  • 栈:不需要额外回收,他是每个线程私有的,线程销毁之后,自然就回收了.
  • 元数据区:一般也不需要,都是加载类,很少卸载类.

3.2 GC的工作流程

GC的工作流程分为两步:

  1. 找到谁是垃圾
  2. 释放对应的内存

3.2.1 判断谁是垃圾

判定一个对象是否是垃圾,判定的方式比较保守.判定某个对象是否存在引用指向它.使用对象,都是通过引用的方式来使用的,如果没有引用指向这个对象,意味着这个对象无法再代码中使用.于是就可以视为垃圾.

  • 引用计数算法
    [注意] 这种算法是PHP和python采用的算法,不是JVM采用的算法.
    给对象增加⼀个引用计数器,每当有⼀个地方引用它时,计数器就+1;当引用失效时,计数器就-1;任何时刻计数器为0的对象就是不能再被使用的,即对象已"死".
    在这里插入图片描述
    但是这种方法存在很大的缺点,所以JVM才没有采用这样的方式.
    • 额外消耗的存储空间较大
    • 引用计数无法解决对象的循环引用问题
      什么是对象循环引用问题,我们来看下面这样一段代码.
    • 首先创建了两个对象,并使用a,b引用指向他们,对象的计数+1.
    • 之后两个对象中的t成员变量分别指向对方的引用,对象的计数+1.
    • 之后让a,b指向null,a,b指向的对象的计数-1,但是还没有减为零,所以两个对象没有被视为垃圾回收掉.
class Test{
	Test t;
}
public static void main(String[] args){
	Test a = new Test();
	Test b = new Test();
	a.t = b;
	b.t = a;
	a = null;
	b = null;
}

在这里插入图片描述

  • 可达性分析算法
    为了避免上述的两个问题,所以JVM引入了可达性分析算法.解决了空间和循环引用的问题.但是也付出了时间上的代价.
    这种算法的核心思想就是:遍历.
    JVM把对象之间的引用关系,理解为一个树形结构.JVM会不停遍历这样的结构,把所有可能遍历访问到的对象标记为"可达",剩下的是"不可达".
    例如下面这棵树:
    在这里插入图片描述

从root出发,任何一个树上的结点都可达.
如果现在令c.right = null,这样的话,f也无法访问到了,f就会被标记为"不可达",就会把f标记为垃圾.a.right = null,此时c就不可达,f也不可达,c和f也会被标记为垃圾.
JVM会周期性对所有的树进行遍历,不停标记可达/不可达.

3.2.2 释放对应内存(垃圾回收)

把垃圾标记出来之后,就要对垃圾进行回收操作了.

  • 标记-清除算法
    这个算法分为标记和清除两个阶段.首先需要标记出所有需要回收的对象,在标记完成后统一回收所有被标记的对象.
    但是这种算法有一些不足:
    • 效率问题:标记和清除这两个过程的效率都不高.
    • 空间问题:标记清除之后会产生大量的不连续的内存碎片,空闲的内存被分成了一个碎片,不集中.空间碎片太多可能会导致以后子啊程序运行的时候需要分配较大对象的时候,无法找到足够连续的内存.
      在这里插入图片描述
  • 复制算法
    当这块内存需要进行垃圾回收时,会将此区域还存活着的对象复制到另⼀块上面,然后再把已经使用过的内存区域⼀次清理掉.
    在这里插入图片描述
    但是这种做法也有一个致命的缺点:复制的时间开销很大.
  • 标记-整理算法
    标记过程仍与"标记-清除"过程⼀致,但后续步骤不是直接对可回收对象进行清理,而是让所有存活对象都向⼀端移动,然后直接清理掉端边界以外的内存.;类似于顺序表删除中间元素的操作.
    在这里插入图片描述
    这种算法实质上和复制算法差别不大,也是会涉及到复制操作,也会产生较大的时间开销.
  • 分代算法
    这种算法就是根据对象的年龄进行垃圾回收.所谓的年龄就是经过GC扫描的次数.按照年龄,把对象分为新生代和老年带,其中新生代又分为伊甸区和生存区.这就和我们前面所提到的堆的数据区接轨了.
    在这里插入图片描述
    • 新创建的对象,会被放到伊甸区,伊甸区的大部分对象,生命周期都比较短,第一轮GC就有可能成为垃圾,只有极少数可以活过第一轮来到生存区.
    • 生存区有两个,每经过一轮GC,生存区都会淘汰一批对象,剩下的进入到另一个生存区,到达另一个生存区是通过复制实现的.此外还有伊甸区新来的对象.每复制一次,年龄+1.就这样在两个生存区之间来回周转.
    • 老年代对象也要经过GC,但是老年代的生命周期更长,就可以降低GC的频率.这里对老年代的GC,是通过标记=整理算法来完成的.

举例说明:校招找工作

  • 伊甸区:投放简历,大量简历被直接淘汰
  • 生存区:简历通过,要经过笔试,技术面,HR面等多轮筛选.
  • 老年代:进入公司,但是会定期考核.

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

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

相关文章

MySQL: 表的增删改查(基础)

文章目录 1. 注释2. 新增(Create)3. 查询(Retrieve)3.1 全列查询3.2 指定列查询3.3 查询字段为表达式3.4 别名3.5 去重: distinct3.6 排序: order by3.7条件查询3.8 分页查询 4. 修改 (update)5. 删除(delete)6. 内容重点总结 1. 注释 注释:在SQL中可以使用“–空格…

【React】Redux与React - 环境准备

配套工具 在React中使用redux,官方要求安装俩个其他插件 - Redux Toolkit 和 react-redux 配置基础环境 使用 CRA 快速创建 React 项目 npx create-react-app react-redux安装配套工具 npm i reduxjs/toolkit react-redux启动项目 npm run start

python中while循环实现九九乘法表

i 1while i < 9: # 控制行的循环j 1while j < i: # 控制每行的输出print(f"{j}*{i}{j * i}\t", end"")j 1print()i 1运行截图&#xff1a;

图解 Python 编程(12) | 文件和编码方式

&#x1f31e;欢迎来到Python 的世界 &#x1f308;博客主页&#xff1a;卿云阁 &#x1f48c;欢迎关注&#x1f389;点赞&#x1f44d;收藏⭐️留言&#x1f4dd; &#x1f31f;本文由卿云阁原创&#xff01; &#x1f4c6;首发时间&#xff1a;&#x1f339;2024年6月9日&am…

《编译原理》期末考试复习手写笔记(二)+真题(第四、五、六章)+课后习题答案

第四章考试题型【自顶向下语法分析】 考点梳理&#xff1a; 1.语法分析程序的设计 2.确定的自顶向下分析思想2.1 FIRST集合 2.2 FOLLOW集合 2. 3 SELECT集合 2. 4 LL(1)文法 3.LL(1)文法的判别 如何消除左公因子? 如何消除左递归? 4.非LL(1)到LL(1)文法的等价变换 5.LL(1)分…

Web后端开发(请求-简单参数)(一)

原始方式&#xff1a; 在原始的web程序中&#xff0c;获取请求参数&#xff0c;需要通过HttpServletRequest 对象手动获取。 RequestMapping("/simpleParam") public String simpleParam(HttpServletRequest request){//获取请求参数String name request.getParame…

物资材料管理系统建设方案(Word)—实际项目方案

二、 项目概述 2.1 项目背景 2.2 现状分析 2.2.1 业务现状 2.2.2 系统现状 三、 总体需求 3.1 系统范围 3.2 系统功能 3.3 用户分析 3.4 假设与依赖关系 四、 功能需求 4.4.11.7 非功能性需求 五、 非功能性需求 5.1 用户界面需求 5.2 软硬件环境需求 5.3 产品质量需求 5.4 接口…

springAOP 使用aop代替SqlsessionUtil业务层操作

在Maven框架pom配置文件中导入spring相关依赖&#xff1a; <dependencies><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.33</version></dependency><dependency…

爬虫可以不必自己写,使用ChatGPT编写抓取电影评论数据脚本

经常去新华书店看看有没有什么新书上架&#xff0c;还是更新挺及时的&#xff0c;可以反映新的技术趋势。这不&#xff0c;最近就看到了这本《巧用 ChatGPT 快速搞定数据分析》&#xff0c;作者是个大牛&#xff0c;第一次看到prompt可以这么写&#xff0c;得写这么长&#xff…

LeMeViT:具有可学习元令牌的高效ViT

本文提出使用可学习的元令牌来制定稀疏令牌&#xff0c;这有效地学习了关键信息&#xff0c;同时提高了推理速度。从技术上讲&#xff0c;主题标记首先通过交叉关注从图像标记中初始化。提出了双交叉注意&#xff08;DCA&#xff09;来促进图像令牌和元令牌之间的信息交换&…

【JS】理解闭包及其应用

历史小剧场 明朝灭亡&#xff0c;并非是简单的政治问题&#xff0c;事实上&#xff0c;这是世界经济史上的一个重要案例。 所谓没钱&#xff0c;就是没有白银。----《明朝那些事儿》 什么是闭包&#xff1f; 闭包就是指有权访问另一个函数作用域中变量的函数 闭包变量存储位置&…

数据结构【堆排序】

前言 在上一篇文章主要讲解了二叉树的基本概念和堆的概念以及接口的实现&#xff08;点此处跳转&#xff09; 我们简回顾下堆的基本概念&#xff1a; 1.堆分为大堆和小堆 大堆&#xff1a;父亲结点比左右孩子都大&#xff0c;根结点是最大的小堆&#xff1a;父亲结点比左右孩…

关于CodeCombat(沙漠)布朗噪声的攻略

关于CodeCombat(沙漠)//布朗噪声的攻略 总的来说怎么猥琐怎么来 1.走到墙角骷髅看不到的位置&#xff0c;让宠物制造噪音&#xff0c;然后英雄走过去&#xff0c;就是这样没错&#xff08;坐标之类能明白) 最后看看运行结果吧 Rec 0002 希望天天开心

CAN协议简介

协议简介 can协议是一种用于控制网络的通信协议。它是一种基于广播的多主机总线网络协议&#xff0c;常用于工业自动化和控制领域。can协议具有高可靠性、实时性强和抗干扰能力强的特点&#xff0c;被广泛应用于汽车、机械、航空等领域。 can协议采用了先进的冲突检测和错误检测…

C++系统编程篇——linux软件包管理器yum

Linux 软件包管理器yum (1)linux系统&#xff08;centos生态&#xff09; 安装方式有三种&#xff1a;源代码安装、rpm安装、yum安装&#xff08;最简单&#xff09; ls /etc/yum.repos.d/ 查看该路径下的文件 包含了用于配置 YUM 软件包管理器的仓库配置文件。这些配置文件…

QT-轻量级的笔记软件MyNote

MyNote v2.0 一个轻量级的笔记软件&#x1f4d4; Github项目地址: https://github.com/chandlerye/MyNote/tree/main 应用简介 MyNote v2.0 是一款个人笔记管理软件&#xff0c;没有复杂的功能&#xff0c;旨在提供便捷的笔记记录、管理以及云同步功能。基于Qt 6.6.3 个人开…

ASUS华硕ROG幻14Air笔记本GA403UI(UI UV UU UJ)工厂模式原厂Windows11系统安装包,带MyASUS in WinRE重置还原

适用型号&#xff1a;GA403UI、GA403UV、GA403UU、GA403UJ 链接&#xff1a;https://pan.baidu.com/s/1tz8PZbYKakfvUoXafQPLIg?pwd1mtc 提取码&#xff1a;1mtc 华硕原装WIN11系统工厂包带有ASUS RECOVERY恢复功能、自带面部识别,声卡,显卡,网卡,蓝牙等所有驱动、出厂主题…

大模型的演进之路:从萌芽到ChatGPT的辉煌

文章目录 ChatGPT&#xff1a;大模型进化史与未来展望引言&#xff1a;大模型的黎明统计模型的奠基深度学习的破晓 GPT系列&#xff1a;预训练革命GPT的诞生&#xff1a;预训练微调的范式转换GPT-2&#xff1a;规模与能力的双重飞跃GPT-3&#xff1a;千亿美元参数的奇迹 ChatGP…

(三)React事件

1. React基础事件绑定 语法&#xff1a; on 事件名称 { 事件处理程序 }&#xff0c;整体上遵循驼峰命名法 App.js //项目根组件 //App -> index.js -> public/index.html(root)function App() {const handleClick () > {console.log(button被点击了)}return (<…

Data Mining2 复习笔记6 - Optimization Hyperparameter Tuning

6. Optimization & Hyperparameter Tuning Why Hyperparameter Tuning? Many learning algorithms for classification, regression, … Many of those have hyperparameters: k and distance function for k nearest neighbors, splitting and pruning options in decis…