Java面试题: JVM虚拟机常见面试题(一)

收集大量Java经典面试题目📚,内容涵盖了包括了:Java面试、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafka 等知识点🏝️。适合准备Java面试的读者参考和复习🌟📢。

❗ ❗ ❗ 关注公众号:枫蜜柚子茶 ✅✅🗳
📑 回 复 “ Java面试 ” 获 取 完 整 资 料⬇ ⬇ ⬇

📖JVM虚拟机常见面试题🔥🔥
1️⃣ 基 础 知 识 🚩
2️⃣ 进 阶 理 论
3️⃣ 实 战 项 目  

基础知识

1.1JDK、 JRE 、JVM的关系是什么?

什么是 JVM?

        英文名称 (Java Virtual Machine) 就是 JAVA虚拟机I   它只识别  .class  类型文件I它 能够将 class文件中的字节码指令进行识别并调用操作系统向上的 API完成动作。

什么是 JRE ?

        英文名称( Java Runtime Environment ) Java 运行时环境。它主要包含两个部分:   JVM 的标准实现和 Java的—些基本类库。相对于 JVM来说IJ RE多出来—部分 Java 库。

什么是 JDK?

        英文名称( Java Development Kit) Java 开发工具包。JDK是整个 Java开发的核心,它集成了 JRE和—些好用的小工具。例如:javac.exejava.exejar.exe等。

❗ 这三者的关系:  —层层的嵌套关系。JDK>JRE>JVM。

1.2JVM的内存模型以及分区情况和作用

如下图所示 :

黄色部分为线程共有,蓝色部分为线程私有。 

🔹 方法区

用于存储虚拟机加载的类信息,常量,静态变量等数据。 

🔹 堆

存放对象实例,所有的对象和数组都要在堆上分配。   是 JVM所管理的内存中最大的—块 区域。

🔹 栈

Java方法执行的内存模型:存储局部变量表,操作数栈,动态链接,方法出口等信息。 生命周期与线程相同。

🔹 本地方法栈

作用与虚拟机栈类似,不同点本地方法栈为 native方法执行服务,虚拟机栈为虚拟机执 行的 Java方法服务。

🔹 程序计数器

当前线程所执行的行号指示器。是 JVM 内存区域最小的—块区域。执行字节码工作时就 是利用程序计数器来选取下—条需要执行的字节码指令。

1.3垃圾回收算法有几种类型?  他们对应的优缺点又是什么?

常见的垃圾回收算法有:标记-清除算法、复制算法、标记-整理算法、分代收集算法

标记-清除算法

标记—清除算法包括两个阶段:“标记”和“清除”。 标记阶段:  确定所有要回收的对象,并做标记。清除阶段:  将标记阶段确定不可用的对象清除。

缺点:

1.标记和清除的效率都不高。

2.会产生大量的碎片,而导致频繁的回收。 

复制算法

内存分成大小相等的两块,每次使用其中—块,当垃圾回收的时候, 把存活的对象复制到另—块上,然后把这块内存整个清理掉。

缺点:

1.需要浪费额外的内存作为复制区。

2.当存活率较高时,复制算法效率会下降。 

标记-整理算法

标记—整理算法不是把存活对象复制到另—块内存,而是把存活对象往内存的—端移动,然后直接回收边界以外的内存。

缺点:

算法复杂度大,执行步骤较多 .

分代收集算法

目前大部分 JVM的垃圾收集器采用的算法。根据对象存活的生命周期将内存划分为若干 个不同的区域。—般情况下将堆区划分为新生代( young Generation老年代( Tenured Generation ),永久代( per manet Generation)。

老年代的特点是每次垃圾收集时只有少量对象需要被回收,而新生代的特点是每次垃圾 回收时都有大量的对象需要被回收,那么就可以根据不同代的特点采取最适合的收集算法。

如下图所示 :

◾ Young:存放新创建的对象,对象生命周期非常短,几乎用完可以立即回收,也叫 Eden 区。

◾ Tenured:young区多次回收后存活下来的对象将被移到 tenured区,也 old区。 perm:永久带,主要存加载的类信息,生命周期长,几乎不会被回收。

缺点:

算法复杂度大,执行步骤较多。

 1.4JVM对象创建步骤流程是什么?

整体流程如下图所示:

  • 第1步:虚拟机遇到—个 new指令,首先将去检查这个指令的参数是否能在常量池中定 位到这个类的符号引用,   并且检查这个符号引用的类是否已经被加载&解析&初始化。
  • 2步:如果类已经被加载那么进行第 3步; 如果没有进行加载,   那么就就需要先进行 类的加载。
  • 3步:类加载检查通过之后,   接下来进行新生对象的内存分配。
  • 4步:对象生成需要的内存大小在类加载完成后便可完全确定,为对象分配空间等同 于把—块确定大小的内存从 Java堆中划分出来
  • 5步:内存大小的划分分为两种情况:
  • ▪  第—种情况:JVM的内存是规整的,   所有的使用的内存都放到—边,   空闲的内存在另外 —边,   中间放—个指针作为分界点的指示器。   那么这时候分配内存就比较简单,   只要 讲指针向空闲空间那边挪动—段与对象大小相同的距离。  这种就是“指针碰撞”。
  • ▪  第二种情况:JVM 的内存不是规整的,   也就是说已使用的内存与未使用的内存相互交 错。 这时候就没办法利用指正碰撞了。  这时候我们就需要维护—张表,用于记录那些内 存可用,   在分配的时候从列表中找到—块足够大的空间划分给对象实例,   并更新到记录 表上。
  • 6步:空间申请完成之后,   JVM需要将内存的空间都初始化为 。值。如果使用 TLAB, 就可以在 T LAB分配的时候就可以进行该工作。
  • 第7步: JVM对对象进行必要的设置。   例如,   这个对象是哪个类的实例、对象的哈希 码、GC年代等信息。
  • 第 8步:完成了上面的步骤之后 JVM来看—个对象基本上完成了,   但从 Java 程序代 码绝对来看,   对象创建才刚刚开始,   需要执行 <ínít>方法,   按照程序中设定的初始化 操作初始化 ,   这时候—个真正的程序对象生成了。

1.5简单介绍—下什么是类加载机制?

class文件由类装载器装载后,在 JVM 中将形成—份描述 class结构的元信息对象,通过 该元信息对象可以获知 class的结构信息:如构造函数,属性和方法等。

虚拟机把描述类的数据从 class文件加载到内存,并对数据进行校验,转换解析和初始 化,最终形成可以被虚拟机直接使用的 Java类型,这就是虚拟机的类加载机制。

1.6类的加载过程是什么?简单描述—下每个步骤

类加载的过程包括了:加载、验证、准备、解析、初始化五个阶段。

第1️⃣步:加载

查找并加载类的二进制数据。加载是类加载过程的第—个阶段,虚拟机在这—阶段需要完成以下三件事情:

        ◾ 通过类的全限定名来获取其定义的二进制字节流

        ◾ 将字节流所代表的静态存储结构转化为方法区的运行时数据结构

        ◾ 在 Java堆中生成—个代表这个类的 java. lang. class对象,作为对方法区中这些数据 的访问入口。

第2️⃣步:验证

确保被加载的类的正确性。

这—阶段是确保 class文件的字节流中包含的信息符合当前虚拟机的规范,并且不会损 害虚拟机自身的安全。包含了四个验证动作:文件格式验证,元数据验证,字节码验 证,符号引用验证。

第3️⃣步:准备

为类的静态变量分配内存,并将其初始化为默认值。

准备阶段是正式为类变量分配内存并设置类变量初始值的阶段,这些内存都将在方法区 中分配。

第4️⃣步:解析

把类中的符号引用转换为直接引用。

解析阶段是虚拟机将常量池内的符号引用替换为直接引用的过程,解析动作主要针对类 或接口、字段、类方法、接口方法、方法类型、方法句柄和调用点限定符 7类符号引用 进行。

第5️⃣步:初始化

类变量进行初始化

为类的静态变量赋予正确的初始值,  JVM负责对类进行初始化,主要对类变量进行初始 化。

1.7JVM预定义的类加载器有哪几种?分别什么作用?

启动(Bootstrap)类加载器、标准扩展(Extension)类加载器、应用程序类加载器 (Application)

启动(Bootstrap)类加载器

引导类装入器是用本地代码实现的类装入器,它负责将 <Java-Runtìme-Home >/lìb下面 的类库加载到内存中。由于引导类加载器涉及到虚拟机本地实现细节,开发者无法直接 获取到启动类加载器的引用。

标准扩展  (Extension)类加载器

扩展类加载器负责将 <Java-Runtìme-Home >/lìb/ext或者由系统变 java .ext.dìr指定位 置中的类库加载到内存中。开发者可以直接使用标准扩展类加载器。

应用程序类加载器(Application)

应用程序类加载器(Application classLoader):负责加载用户路径(classpath)上的类库。

1.8什么是双亲委派模式?有什么作用?

基本定义:

双亲委派模型的工作流程是:如果—个类加载器收到了类加载的请求,它首先不会自己 去加载这个类,而是把请求委托给父加载器去完成,依次向上,因此,所有的类加载请 求最终都应该被传递到顶层的启动类加载器中,只有当父加载器没有找到所需的类时。

子加载器才会尝试去加载该类。 双亲委派机制:

1.  AppclassLoader加载—个 class时,它首先不会自己去尝试加载这个类,而是把 类加载请求委派给父类加载器 ExtclassLoader去完成。

2. ExtclassLoader加载—个 class时,它首先也不会自己去尝试加载这个类,而是 把类加载请求委派给 BootstrapclassLoader去完成。

3.如果 BootstrapclassLoader加载失败,会使用 ExtclassLoader来尝试加载;

4.若  ExtclassLoader 加 载 失 败 ,   则 会 使 用  AppclassLoader 来 加 载 ,   如 果 AppclassLoader也加载失败,则会报出异常 classNotFound Exception。

如下图所示 :

双亲委派作用:

        ◾ 通过带有优先级的层级关可以避免类的重复加载;

        ◾  保证 Java程序安全稳定运行,  Java核心 ApI定义类型不会被随意替换。

1.9介绍—下 JVM中垃圾收集器有哪些?  他们特点分别是什么?

新生代垃圾收集器 serial收集器

特点:

serial收集器只能使用—条线程进行垃圾收集工作,并且在进行垃圾收集的时候,所有 的工作线程都需要停止工作,等待垃圾收集线程完成以后,其他线程才可以继续工作。

使用算法:  复制算法 

parNew收集器

特点:

parNew垃圾收集器是serial收集器的多线程版本。为了利用 cpU 多核多线程的优势,   parNew收集器可以运行多个收集线程来进行垃圾收集工作。这样可以提高垃圾收集过程 的效率。

使用算法:  复制算法

parallelscavenge收集器

特点:

parallel scavenge收集器是—款多线程的垃圾收集器,但是它又和 parNew有很大的不同 点。

parallel scavenge收集器和其他收集器的关注点不同。其他收集器,比如 parNewcMs 这些收集器 ,它们主要关注的是如何缩短垃圾收集的时间。而 parallel scavenge收集器 关注的是如何控制系统运行的吞吐量。这里说的吞吐量,指的是 cpU用于运行应用程序 的时间和 cpU总时间的占比,吞吐量 =代码运行时间 /   (代码运行时间 +垃圾收集时 间)。如果虚拟机运行的总的 cpU时间是 100分钟,而用于执行垃圾收集的时间为 1分 钟,那么吞吐量就是 99%。

使用算法:  复制算法 

老年代垃圾收集器

serialold收集器

特点:

serial old收集器是 serial收集器的老年代版本。这款收集器主要用于客户端应用程序中 作为老年代的垃圾收集器,也可以作为服务端应用程序的垃圾收集器。

使用算法:标记-整理 

parallelold收集器

特点:

parallel old收集器是 parallel Scavenge收集器的老年代版本这个收集器是在 J DK1.6版本 中出现的,  所以在 J DK1.6之前,新生代的 parallel Scavenge只能和 Serial old这款单线程 的老年代收集器配合使用。parallel old垃圾收集器和 parallel Scavenge收集器—样,也 是—款关注吞吐量的垃圾收集器,和 parallel Scavenge收集器—起配合,可以实现对 Java堆内存的吞吐量优先的垃圾收集策略。

使用算法:  标记-整理 

CMS收集器

特点:

CMS收集器是目前老年代收集器中比较优秀的垃圾收集器。CMS Concurrent Mark Sweep,从名字可以看出,这是—款使用”标记-清除”算法的并发收集器。

CMS垃圾收集器是—款以获取最短停顿时间为目标的收集器。如下图所示:

从图中可以看出,  CMS收集器的工作过程可以分为 4个阶段:

        ◾ 初始标记(CMS initial mark)阶段

        ◾ 并发标记(CMS concurrent mark)阶段

        ◾ 重新标记(CMS remark)阶段

        ◾ 并发清除((CMS concurrent sweep)阶段 使用算法:  复制+标记清除

        ◾ 其他

G1垃圾收集器

特点:

主要步骤:   初始标记,并发标记,重新标记,复制清除。 

使用算法:复制 +标记整理

1.10什么是 Class文件?  Class文件主要的信息结构有哪些?

class文件是—组以 8位字节为基础单位的二进制流。各个数据项严格按顺序排列。

class文件格式采用—种类似于 c语言结构体的伪结构来存储数据。这样的伪结构仅仅有 两种数据类型:无符号数和表。

无符号数:是基本数据类型。以 u1、u2、u4、u8分别代表 1个字节、2个字节、4个字 节、8个字节的无符号数,能够用来描写叙述数字、索引引用、数量值或者依照 UTF-8 编码构成的字符串值。

:由多个无符号数或者其它表作为数据项构成的复合数据类型。全部表都习惯性地以 - info 结尾。

1.11对象“对象已死”是什么概念?

对象不可能再被任何途径使用,称为对象已死。

判断对象已死的方法有:引用计数法与可达性分析算法。

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

枫蜜柚子茶

你的鼓励是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值