【JVM】之常见面试题

文章目录

  • 1.JVM中的内存区域划分
  • 2.JVM的类加载机制
    • 2.1 加载
    • 2.2 验证
    • 2.3 准备
    • 2.4 解析
    • 2.5 初始化
    • 2.6 类加载的时机
  • 3 类加载器
  • 4.双亲委派模型
  • 5.JVM中的垃圾回收策略
    • 5.1 找谁是垃圾
      • 5.1.1 引用计数法
      • 5.1.2 可达性分析法
    • 5.2 释放垃圾
      • 5.2.1 标记清除算法
      • 5.2.2 复制算法
      • 5.2.3 标记整理算法
      • 5.2.4 分代算法

1.JVM中的内存区域划分

JVM就是一个Java进程,Java进程会从操作系统这里申请一大块内存空间,给Java代码来使用。
而这一大块内存空间又可以进一步细分为以下几个最核心的内存区域:

  • 堆:存放的是new出来的对象,即成员变量。
  • 栈:存放的是方法与方法之间的调用关系,即局部变量。
  • 方法区(旧)/元数据区(新):存放的是类加载之后的类对象(.class,Test.class),即静态变量。

这块的主要考点就是给一段代码,判断某个变量处于内存中的哪个位置,需要注意是的,我们是通过变量的形态(成员变量,局部变量,静态变量)来判断,而不是通过变量的类型来判断。

例如下面的例子:

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

在这里插入图片描述
接下来我们就系统的介绍一下JVM运行时数据区,也叫JVM的内存布局。按照 Java 的虚拟机规范,可以细分为程序计数器、虚拟机栈、本地方法栈、堆、方法区等,如下图:
在这里插入图片描述
其中堆和方法区在一个JVM进程中只有一份,而栈(虚拟机栈和本地方法栈)和程序计数器则是有多份的,每一个线程有一份。

  • 程序计数器 : 也叫PC寄存器,用途是记录当前程序执行到哪个指令了,它是一个简单的long类型变量,里面存了一个内存地址,这个内存地址就是下一个要执行的字节码的内存地址。
  • Java虚拟机栈:通常就是指”栈“,它的生命周期和线程一样,当线程执行一个方法时,会创建一个对应的栈帧,用于存储局部变量表、操作数栈、动态链接、方法出口等信息,然后栈帧会被压入栈中。当方法执行完毕后,栈帧会从栈中移除。
  • 本地方法栈:是给JVM内部的本地方法使用的(JVM内部通过C++实现的方法)。
  • :堆(heap)是 JVM 中最大的一块内存区域,被所有线程共享,在 JVM 启动时创建,主要用来存储对象的。
  • 方法区:用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。方法区也是所有线程共享的。

2.JVM的类加载机制

.class 文件需要加载到虚拟机中之后才能运行和使用,类加载的过程就是将.class文件加载到内存中得到类对象的过程。其中类加载的过程分为五步,即加载→验证→准备→解析→初始化,如下图所示:
在这里插入图片描述

2.1 加载

加载阶段就是查找并加载类的二进制数据(.class文件),在加载阶段,JVM做三件事情:

  1. 通过一个类的全限定名来获取定义此类的二进制字节流。
  2. 将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构。
  3. 在内存中生成一个代表这个类的 java.lang.Class 对象,作为方法区这个类的各种数据的访问入口。

2.2 验证

这一阶段的目的是确保 Class 文件的字节流中包含的信息符合《Java 虚拟机规范》的全部约束要求,保证这些信息被当作代码运行后不会危害虚拟机自身的安全。验证包括了:文件格式验证(二进制文件)、字节码验证,符号引用验证

2.3 准备

在准备阶段,JVM会给类对象分配内存空间并设置初始值,初始值为数据类型的默认初始值,如0,0L,false,null等。

2.4 解析

解析阶段是虚拟机将常量池中的符号引用替换为直接引用的过程。

其中符号引用就是字符串常量,它在.class文件中已经存在了,但它们之间只知道彼此的相对位置(偏移量),并不知道自己在内存中的实际位置,而当真正加载到内存中的时候,就会把字符串常量填充到特定的位置上,字符串常量之间的相对位置还是一样的,但此时它们有了实际的内存地址,此时的字符串常量就是直接引用了(Java中的普通引用)。

2.5 初始化

初始化阶段就是针对类对象进行初始化(初始化静态成员,执行静态代码块,如果该类还有父类还需加载它的父类)。

2.6 类加载的时机

JVM 启动的时候,并不会一次性加载所有的类,而是根据需要去动态加载。也就是说,大部分类在具体用到的时候才会去加载,这样对内存更加友好。
那么什么是需要的时候呢?

  1. 创建了这个类的实例
  2. 使用了这个类的静态方法/静态属性
  3. 使用子类,也会触发父类的加载

3 类加载器

在介绍双亲委派模型之前,我们需要先知道JVM加载类时需要用到一组特殊的模块,即类加载器。
类加载器(ClassLoader)用于动态加载 Java 类到 Java 虚拟机中。主要有四种类加载器:

  1. 启动类加载器(Bootstrap ClassLoader)负责加载Java标准库中的类。

  2. 扩展类加载器(Extension ClassLoader):负责加载一些非标准的但是Sum/Oracle扩展的类

  3. 应用程序类加载器(Application ClassLoader):负责加载项目中自己写的类以及第三方库中的类。

  4. 用户自定义类加载器 (User-Defined ClassLoader),我们可以通过继承java.lang.ClassLoader类来创建自己的类加载器。

4.双亲委派模型

在上面我们介绍了JVM类加载的过程,而这就不得不提到一个重要的考点了——双亲委派模型。
它发生在第一步加载中找.class文件的时候,是 Java 类加载机制中的一个重要概念。这种模型指的是一个类加载器在尝试加载某个类时,首先会将加载任务委托给其父类加载器去完成。只有当父类加载器无法完成这个加载请求(即它找不到指定的类)时,子类加载器才会尝试自己去加载这个类。 如下图所示:

在这里插入图片描述

  • 当一个类加载器需要加载某个类时,它首先会请求其父类加载器加载这个类。
  • 这个过程会一直向上递归,也就是说,从子加载器到父加载器,再到更上层的加载器,一直到最顶层的启动类加载器(Bootstrap ClassLoader)。
  • 启动类加载器会尝试加载这个类。如果它能够加载这个类,就直接返回;如果它不能加载这个类(因为这个类不在它的搜索范围内),就会将加载任务返回给委托它的子加载器。
  • 子加载器接着尝试加载这个类。如果子加载器也无法加载这个类,它就会继续向下传递这个加载任务,依此类推。
  • 这个过程会继续,直到某个加载器能够加载这个类,或者所有加载器都无法加载这个类,最终抛出 ClassNotFoundException。

5.JVM中的垃圾回收策略

垃圾回收(Garbage Collection,GC),顾名思义就是释放垃圾占用的空间,防止内存爆掉。有效的使用可以使用的内存,对内存堆中已经死亡的或者长时间没有使用的对象进行清除和回收。
而垃圾回收之前我们需要先清楚谁是垃圾,谁不是垃圾,即GC分为了两步,先是找谁是垃圾,再对垃圾进行释放。

5.1 找谁是垃圾

常用的垃圾判断算法有引用计数算法,可达性分析算法。

5.1.1 引用计数法

引用计数法:给对象增加一个引用计数器,每当有一个地方引用该对象时,计数器+1,当引用失效时,计数器-1,任何时候计数器为 0 的对象就是不可能再被使用的。
优点:实现简单,效率高
缺点:无法解决循环引用的问题

5.1.2 可达性分析法

这个算法的基本思想就是通过一系列的称为 “GC Roots” 的对象作为起点,从这些节点开始向下搜索,节点所走过的路径称为引用链,当一个对象到 GC Roots 没有任何引用链相连的话,即从 GC Roots 到该对象节点不可达,则证明该对象是需要垃圾收集的。
在这里插入图片描述
可以作为GC Roots的对象:

  • 栈上的局部变量(每个栈的每个局部变量都是起点)
  • 常量池中引用的对象
  • 方法区中,静态变量引用的对象

5.2 释放垃圾

在确定了哪些垃圾可以被回收后,垃圾收集器要做的事情就是进行垃圾回收,如何高效地进行垃圾回收呢?

5.2.1 标记清除算法

标记清除算法,分为 2 部分,先把内存区域中的这些对象进行标记,哪些属于可回收的标记出来,然后把这些垃圾拎出来清理掉。
在这里插入图片描述

优点:实现简单。

缺点:产生大量不连续的内存碎片。当我们想申请一块连续的较大的内存时,可能就申请不到。

5.2.2 复制算法

在标记清除算法上演化而来的,用于解决标记清除算法的内存碎片问题。它将可用内存按容量划分为大小相等的两块,每次只使用其中的一块。
在这里插入图片描述
优点:执行效率高,没有内存碎片的问题。

缺点:空间利用率低,因为复制算法每次只能使用一半的内存。

5.2.3 标记整理算法

标记整理算法,标记过程仍然与标记清除算法一样,但后续步骤不是直接对可回收对象进行清理,而是让所有存活的对象都向一端移动,再清理掉端边界以外的内存区域。
在这里插入图片描述
优点:解决了内存碎片问题,比复制算法空间利用率高。

缺点:因为有局部对象移动,所以效率不是很高。

5.2.4 分代算法

当前虚拟机的垃圾收集都采用分代收集算法,是根据对象存活周期的不同将内存分为几块。一般将 Java 堆分为新生代和老年代,这样我们就可以根据各个年代的特点选择合适的垃圾收集算法。
由于新生代存放的大部分数据是朝生夕死的,所以新生代使用的是效率最高的复制算法;而老生代使用的是标记-清除或标记-整理算法,如果标记-清除可以满足需要那么就使用效率更好的标记-清除算法,如果标记-清除算法不能满足需要就使用标记-整理算法。

在这里插入图片描述
今天的分享到这里就结束了,感谢支持!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

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

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

【Python】已完美解决:(Python键盘中断报错问题) KeyboardInterrupt

文章目录 一、问题背景二、可能出错的原因三、错误代码示例四、正确代码示例(结合实战场景)五、注意事项 已解决:Python中处理KeyboardInterrupt(键盘中断)报错问题 一、问题背景 在Python编程中,当我们运…

uni-date-picker 禁用日期功能

在uni-datetime-picker组件中 calendar.vue <template><view class"uni-calendar" mouseleave"leaveCale"><view v-if"!insert && show" class"uni-calendar__mask" :class"{uni-calendar--mask-show:an…

Python-Socket网络编程简单示例

# TCP 服务端程序 server.py # 导入socket 库 from socket import *# 主机地址为空字符串&#xff0c;表示绑定本机所有网络接口ip地址 # 等待客户端来连接 IP # 端口号 PORT 50000 # 定义一次从socket缓冲区最多读入512个字节数据 BUFLEN 512# 实例化一个socket对象 # 参…

【kubernetes】k8s集群安全机制 保姆级攻略

目录 一、认证&#xff08;Authentication&#xff09; Kubernetes 作为一个分布式集群的管理工具&#xff0c;保证集群的安全性是其一个重要的任务。API Server 是集群内部各个组件通信的中介&#xff0c; 也是外部控制的入口。所以 Kubernetes 的安全机制基本就是围绕保护 A…

牛客 NC129 阶乘末尾0的数量【简单 基础数学 Java/Go/PHP/C++】

题目 题目链接&#xff1a; https://www.nowcoder.com/practice/aa03dff18376454c9d2e359163bf44b8 https://www.lintcode.com/problem/2 思路 Java代码 import java.util.*;public class Solution {/*** 代码中的类名、方法名、参数名已经指定&#xff0c;请勿修改&#xff…

LabVIEW结构体内部缺陷振动检测

结构体内部缺陷会改变其振动特性&#xff0c;通过振动分析可以检测并定位这些缺陷。本文详细分析内部缺陷对振动的影响&#xff0c;从频谱分析、时域分析和模态分析等多角度探讨基于LabVIEW的检测方法&#xff0c;提供实施步骤和注意事项&#xff0c;帮助工程师有效利用LabVIEW…

1224 - 过河卒

题目描述 AA 点有一个过河卒&#xff0c;需要走到目标 BB 点。 卒行走规则&#xff1a;可以向下、或者向右。同时在棋盘上的任一点有一个对方的马&#xff08;如下图的 CC 点&#xff09;&#xff0c;该马所在的点和所有跳跃一步可达的点称为对方马的控制点。 例如&#xff…

哪个牌子洗地机最好?四款甄选佳品安利,质量放心

作为一个熟悉智能清洁家电的行业者&#xff0c;洗地机可谓是实用性最高的地面清洁工具&#xff0c;这个实用性一方面是清洁力强&#xff0c;它集合了扫地和拖地能力&#xff0c;另一方面是操作方便&#xff0c;清洁速度快。可是面对市面上种类繁多的智能清洁家电&#xff0c;往…

C语言之数组

目录 一、数组的概念 二、一维数组的使用 数组的创建 数组的初始化 数组的使用 三、一维数组在内存中的存储 四、sizeof计算数组元素个数 五、二维数组的使用 数组的创建 数组的初始化 数组的使用 六、二维数组在内存中的存储 七、C99中的变长数组 八、总结 一、…

“JS加密在线”:简单直接的在线JS加密网站

网站名&#xff1a;“JS加密在线”&#xff0c; 功能&#xff1a;JavaScript源代码加密。 UI&#xff1a; http://jsjiami.online/ 非常简洁的JS加密网站&#xff0c;几乎只有两个功能&#xff1a;上传JS文件、下载加密后的JS文件。 JS加密&#xff0c;就应该这样简单直接。…

AI机器人公众号小程序h5源码开源交付支持二开黑色风格版本

AI机器人系统对接OPENAI&#xff1a;开启智能新纪元 更新全新UI、新增全家桶模块、新增热榜板块、支持语音朗读、支持快速回答、支持AI绘图、支持文字一键生成图、支持导出pdf、支持导出word、支持导出文字、支持快速响应、支持中英翻译、支持markdown &#x1f680;一、引言…

直流遥控器 继电器8-10V应用 降压恒压SL3036电源芯片

在现代电子设备中&#xff0c;电源的稳定性和可靠性对于设备的正常运行至关重要。特别是在直流遥控器这类设备中&#xff0c;由于其需要长时间稳定运行且对电压稳定性要求较高&#xff0c;因此选择一款合适的电源芯片显得尤为重要。本文将重点介绍SL3036电源芯片在直流遥控器继…

爬虫-电影影评爬取

先上代码 import requests import timeheaders {"referer": "http://movie.mtime.com/","user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36" } fo…

Java基础面试重点-2

21. JVM是如何处理异常&#xff08;大概流程&#xff09;&#xff1f; 如果发生异常&#xff0c;方法会创建一个异常对象&#xff08;包括&#xff1a;异常名称、异常描述以及异常发生时应用程序的状态&#xff09;&#xff0c;并转交给JVM。创建异常对象&#xff0c;并转交给…

[SWPUCTF 2022 新生赛]ez_1zpop(php反序列化之pop链构造)

[SWPUCTF 2022 新生赛]ez_ez_unserialize <?php class X {public $x __FILE__;function __construct($x){$this->x $x; }function __wakeup(){if ($this->x ! __FILE__) {$this->x __FILE__; }}function __destruct(){highlight_file($this->x);//flag is…

普涨和补涨—2024年上半年全球投资趋势

全球大宗商品价格处在上涨周期&#xff0c;东吴证券认为上游能源行业股价还有继续上涨的空间。随着6月全球股指进一步上涨&#xff0c;预计港股可能还会迎来补涨行情。 一、我们观察的全球投资趋势&#xff1a; 1、全球股指普涨&补涨。全球风险资产进入2024年后普遍上涨&am…

【Apache Doris】周FAQ集锦:第 5 期

【Apache Doris】周FAQ集锦&#xff1a;第 5 期 SQL问题数据操作问题运维常见问题其它问题关于社区 欢迎查阅本周的 Apache Doris 社区 FAQ 栏目&#xff01; 在这个栏目中&#xff0c;每周将筛选社区反馈的热门问题和话题&#xff0c;重点回答并进行深入探讨。旨在为广大用户和…

bugku---misc---easy_nbt

1、题目描述 2、下载附件&#xff0c;解压之后得到 3、查找资料发现&#xff1a;NBT文件是Minecraft游戏数据文件&#xff0c;其中包含以命名二进制标签(NBT)格式保存的数据。这种格式用于存储大量二进制数据&#xff0c;通常包含有关Minecraft世界的信息。NBT数据通常以.dat文…

机器学习——集成学习和梯度提升决策树

集成学习 不同的算法都可以对解决同一个问题&#xff0c;但是可能准确率不同&#xff0c;集成学习就是不同算法按照某种组合来解决问题&#xff0c;使得准确率提升。 那怎么组合算法呢&#xff1f; 自举聚合算法**&#xff08;bagging&#xff09;** 顾名思义是 自举聚合 自举…