JVM 面经

1、什么是 JVM?

JVM 就是 Java 虚拟机,它是 Java 实现跨平台的基石。程序运行之前,需要先通过编译器将 Java 源代码文件编译成 Java 字节码文件;程序运行时,JVM 会对字节码文件进行逐行解释,翻译成机器码指令,交给对应的操作系统执行。这样就实现了 Java 一次编译,处处运行的特性。
在这里插入图片描述

1.1 说说 JVM 的其他特性?

  1. JVM 可以自动管理内存,通过垃圾回收器回收不再使用的对象并释放内存空间。
  2. JVM 包含一个即时编译器 JIT,它可以在运行时将热点代码缓存到 codeCache 中,下次执行的时候不用再一行一行的解释,而是直接执行缓存后的机器码,执行效率会大幅提高。
  3. 任何可以通过 Java 编译的语言,比如说 Groovy、Kotlin、Scala 等,都可以在 JVM 上运行。

1.2 为什么要学习 JVM ?

学习 JVM 可以帮助我们开发者更好地优化程序性能、避免内存问题。比如:了解 JVM 的内存模型和垃圾回收机制,可以帮助我们更合理地配置内存、减少 GC 停顿。掌握 JVM 的类加载机制可以帮助我们排查类加载冲突或异常。JVM 还提供了很多调试和监控工具,可以帮助我们分析内存和线程的使用情况,从而解决内存溢出内存泄露等问题。

2、说说 JVM 的组织架构

JVM 大致可以划分为三个部分:类加载器、运行时数据区和执行引擎。
在这里插入图片描述

  1. 类加载器:负责从文件系统、网络或其他来源加载 Class 文件,将 Class 文件中的二进制数据读入到内存当中。
  2. 运行时数据区:JVM 在执行 Java 程序时,需要在内存中分配空间来处理各种数据,这些内存区域按照 Java 虚拟机规范可以划分为方法区、堆、虚拟机栈、本地方法栈和程序计数器。
  3. 执行引擎:JVM 的心脏,负责执行字节码。它包括解释器、JIT 编译器和垃圾回收器。

3、能说一下 JVM 的内存区域吗?

按照 Java 虚拟机规范,JVM 的内存区域可以细分为方法区、堆、虚拟机栈、本地方法栈和程序计数器。其中方法区和堆是线程共享的,虚拟机栈、本地方法栈和程序计数器是线程私有的。

3.1 介绍一下方法区?

方法区并不真实存在,是 Java 虚拟机规范中的一个逻辑概念,用于存储已被 JVM 加载的类信息、常量、静态变量、即时编译器编译后的代码缓存等。在 HotSpot 虚拟机中,方法区的实现称为永久代 PermGen,但在 Java 8 及之后的版本中,已经被元空间 Metaspace 所替代。

3.2 介绍一下 Java 堆?

堆是 JVM 中最大的一块内存区域,被所有线程共享,在 JVM 启动时创建,主要用来存储 new 出来的对象。Java 中几乎所有的对象都会在堆中分配,堆也是垃圾收集器管理的目标区域。
在这里插入图片描述
从内存回收的角度来看,由于垃圾收集器大部分都是基于分代收集理论设计的,所以堆又被细分为新生代、老年代、Eden空间、From Survivor空间、To Survivor空间等。
在这里插入图片描述
从 JDK 7 开始,JVM 默认开启了逃逸分析,意味着如果某些方法中的对象引用没有被返回或者没有在方法体外使用,也就是未逃逸出去,那么对象可以直接在栈上分配内存。

3.3 介绍一下 Java 虚拟机栈?

Java 虚拟机栈的生命周期与线程相同。当线程执行一个方法时,会创建一个对应的栈帧,用于存储局部变量表、操作数栈、动态链接、方法出口等信息,然后栈帧会被压入虚拟机栈中。当方法执行完毕后,栈帧会从虚拟机栈中移除。

3.4 介绍一下本地方法栈?

本地方法栈与虚拟机栈相似,区别在于虚拟机栈是为 JVM 执行 Java 编写的方法服务的,而本地方法栈是为 Java 调用本地 native 方法服务的,通常由 C/C++ 编写。

3.5 介绍一下本地方法栈的运行场景?

当 Java 应用需要与操作系统底层或硬件交互时,通常会用到本地方法栈。比如调用操作系统的特定功能,如内存管理、文件操作、系统时间、系统调用等。
在这里插入图片描述
在这里插入图片描述

3.6 native 方法解释一下?

native 方法是在 Java 中通过 native 关键字声明的,用于调用非 Java 语言,如 C/C++ 编写的代码。Java 可以通过 JNI,也就是 Java Native Interface 与底层系统、硬件设备、或者本地库进行交互。

3.7 介绍一下程序计数器?

程序计数器也被称为 PC 寄存器,是一块较小的内存空间。它可以看作是当前线程所执行的字节码行号指示器。

3.8 变量存在堆栈的什么位置?

对于局部变量,它存储在当前方法栈帧中的局部变量表中。当方法执行完毕,栈帧被回收,局部变量也会被释放。对于静态变量来说,它存储在 Java 虚拟机规范中的方法区中,在 Java 7 中是永久代,在 Java 8 及以后是元空间。

4、说一下 JDK 1.6、1.7、1.8 内存区域的变化?

  1. JDK 1.6 使用永久代来实现方法区。
  2. JDK 1.7 依然是永久带,但是将字符串常量池、静态变量存放到了堆上。
  3. JDK 1.8 直接在内存中划出了一块区域,叫元空间,来取代之前放在 JVM 内存中的永久代,并将运行时常量池、类常量池都移动到了元空间。

5、为什么使用元空间替代永久代?

因为永久代受到 JVM 内存大小的限制,会导致 Java 应用程序出现内存溢出的问题。

6、对象创建的过程了解吗?

当我们使用 new 关键字创建一个对象时,JVM 首先会检查 new 指令的参数是否能在常量池中定位到类的符号引用,然后检查这个符号引用代表的类是否已被加载、解析和初始化。如果没有,就先执行类加载。如果已经加载,JVM 会为对象分配内存完成初始化,比如数值类型的成员变量初始值是 0,布尔类型是 false,对象类型是 null。接下来,会设置对象头,里面包含了对象是哪个类的实例、对象的哈希码、对象的 GC 分代年龄等信息。最后,JVM 会执行构造方法 完成赋值操作,将成员变量赋值为预期的值,比如 int age = 18,这样一个对象就创建完成了。
在这里插入图片描述

6.1 对象的销毁过程了解吗?

当对象不再被任何引用指向时,就会变成垃圾。垃圾收集器会通过可达性分析算法判断对象是否存活,如果对象不可达,就会被回收。垃圾收集器通过标记清除、标记复制、标记整理等算法来回收内存,释放对象占用的内存空间。

7、堆内存是如何分配的?

在堆中为对象分配内存时,主要使用两种策略:指针碰撞和空闲列表。指针碰撞适用于管理简单、碎片化较少的内存区域,如年轻代;而空闲列表适用于内存碎片化较严重或对象大小差异较大的场景如老年代。
在这里插入图片描述

  1. 指针碰撞:假设堆内存是一个连续的空间,被分为两个部分,一部分是已经被使用的内存,另一部分是未被使用的内存。在分配内存时,Java 虚拟机会维护一个指针,指向下一个可用的内存地址,每次分配内存时,只需要将指针向后移动一段距离,如果没有发生碰撞,就将这段内存分配给对象实例。
  2. 空闲列表:JVM 会维护一个列表,记录堆中所有未占用的内存块,每个内存块都记录有大小和地址信息。当有新的对象请求内存时,JVM 会遍历空闲列表,寻找足够大的空间来存放新对象。分配后,如果选中的内存块未被完全利用,剩余的部分会作为一个新的内存块加入到空闲列表中。

8、new 对象时,堆会发生抢占吗?

会发生抢占。new 对象时,指针会向右移动一个对象大小的距离,假如一个线程 A 正在给 String 对象 分配内存,另一个线程 B 同时为 ArrayList 对象分配内存,两个线程就发生了抢占。
在这里插入图片描述

8.1 JVM 怎么解决堆内存分配的竞争问题?

为了解决堆内存分配的竞争问题,JVM 为每个线程保留了一小块内存空间,被称为 TLAB,也就是线程本地分配缓冲区,用于存放该线程分配的对象。当线程需要分配对象时,直接从 TLAB 中分配。只有当 TLAB 用尽或对象太大需要直接在堆中分配时,才会使用全局分配指针。
在这里插入图片描述

9、能说一下对象的内存布局吗?

对象的内存布局是由 Java 虚拟机规范定义的,拿我们常用的 HotSpot 来说吧。对象在内存中包括三部分:对象头、实例数据和对齐填充。
在这里插入图片描述

9.1 说说对象头的作用?

对象头是对象存储在内存中的元信息,包含了:Mark Word、类型指针等信息。Mark Word 存储了对象的运行时状态信息,包括锁、哈希值、GC 标记等。在 64 位操作系统下占 8 个字节。类型指针指向对象所属类的元数据,也就是 Class 对象,用来支持多态、方法调用等功能。在开启压缩指针的情况下占 4 个字节,否则占 8 个字节。除此之外,如果对象是数组类型,还会有一个额外的数组长度字段。占 4 个字节。

9.2 实例数据了解吗?

实例数据是对象实际的字段值,也就是成员变量的值,按照字段在类中声明的顺序存储。JVM 会对这些数据进行对齐 / 重排,以提高内存访问速度。

9.3 对齐填充了解吗?

由于 JVM 的内存模型要求对象的起始地址是 8 字节对齐(64 位 JVM 中),因此对象的总大小必须是 8 字节的倍数。如果对象头和实例数据的总长度不是 8 的倍数,JVM 会通过填充额外的字节来对齐。比如说,如果对象头 + 实例数据 = 14 字节,则需要填充 2 个字节,使总长度变为 16 字节。

9.4 为什么非要进行 8 字节对齐呢?

因为 CPU 进行内存访问时,一次寻址的指针大小是 8 字节,正好是 L1 缓存行的大小。如果不进行内存对齐,则可能出现跨缓存行访问,导致额外的缓存行加载,CPU 的访问效率就会降低。8 字节对齐,是一种以空间换时间的方案。
在这里插入图片描述

9.5 new Object() 对象的内存大小是多少?

一般来说,目前的操作系统都是 64 位的,并且 JDK 8 中的压缩指针是默认开启的,因此在 64 位的 JVM 上,new Object()的大小是 16 字节(12 字节的对象头 + 4 字节的对齐填充)。
在这里插入图片描述
假如 MyObject 对象有三个成员变量,分别是 int、long 和 byte 类型,那么它们占用的内存大小分别是 4 字节、8 字节和 1 字节。考虑到对齐填充,MyObject 对象的总大小为 12 + 4 + 8 + 1 + 7(填充)= 32 字节。

9.6 对象的引用(类型指针)大小了解吗?

在 64 位 JVM 上,未开启压缩指针时,对象引用占用 8 字节;开启压缩指针时,对象引用会被压缩到 4 字节。HotSpot 虚拟机默认是开启压缩指针的。

10、JVM 怎么访问对象的?

主流的方式有两种:句柄和直接指针。句柄是通过中间的句柄表来定位对象的,优点是对象被移动时只需要修改句柄表中的指针,而不需要修改对象引用本身。直接指针是通过引用直接存储对象的内存地址的,因为对象的实例数据和类型信息都存储在堆中固定的内存区域。直接指针访问的优点是访问速度更快,因为少了一次句柄的寻址操作。缺点是如果对象在内存中移动,引用需要更新为新的地址。HotSpot 虚拟机主要使用直接指针来进行对象访问。

11、待更新

12、

13、

14、

15、

16、

17、

18、

19、

20、

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

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

相关文章

【JavaScript】合体期功法——DOM(一)

目录 DOMWeb API 基本概念作用和分类 什么是 DOMDOM 树DOM 对象 获取 DOM 元素根据 CSS 选择器来获取 DOM 元素选择匹配的第一个元素选择匹配的多个元素 其他获取 DOM 元素方法 修改元素的内容对象.innerText 属性对象.innerHTML 属性案例:年会抽奖 修改元素属性修改…

GAMMA数据处理(十)

今天向别人请教了一个问题,刚无意中搜索到了一模一样的问题 不知道这个怎么解决... ok 解决了 有一个GAMMA的命令可转换 但是很奇怪 完全对不上 转换出来的行列号 不知道为啥 再试试 是因为经纬度坐标的小数点位数 de as

Java入门知识总结——章节(二)

ps:本章主要讲数组、二维数组、变量 一、数组 数组是一个数据容器,可用来存储一批同类型的数据 🔑:注意 类也可以是一个类的数组 public class Main {public static class Student {String name;int age; // 移除 unsignedint…

动态IP:网络世界的“变色龙”如何改变你的在线体验?

你知道吗?有时候我觉得动态IP就像是网络世界里的“变色龙”。它不像静态IP那样一成不变,而是随时在变化,像是一个永远在换衣服的演员。你永远不知道它下一秒会变成什么样子,但正是这种不确定性,让它变得特别有趣。想象…

从24GHz到71GHz:Sivers半导体的广泛频率范围5G毫米波产品解析

在5G技术的浪潮中,Sivers半导体推出了创新的毫米波无线产品,为通信行业带来高效、可靠的解决方案。这些产品支持从24GHz到71GHz的频率,覆盖许可与非许可频段,适应高速、低延迟的通信场景。 5G通信频段的一点事儿及Sivers毫米波射频…

aocache:AOCache 新增功能深度解析:从性能监控到灵活配置的全方位升级

最近对aocache 进行了重要升级,最新版本0.6.0增加了几项新功能:性能分析日志,AOCache性能分析工具,切入点自定义配置,全局配置,本文详细说明这几项目新功能的作用和使用方式。 一、性能分析日志 需求背景…

Java EE 进阶:MyBatis-plus

MyBatis-plus的介绍 MyBatis-plus是MyBatis的增强工具,在MyBatis的基础上做出加强,只要MyBatis有的功能MyBatis-plus都有。 MyBatis-plus的上手 添加依赖 在我们创建项目的时候,我们需要添加MyBatis-plus和mysql的依赖 MyBatis-plus的依赖…

GitHub和Gitee上的一些AI项目

以下是GitHub和Gitee上的一些AI项目: GitHub上的AI项目 TensorFlow:一个端到端开源机器学习平台,包含大量工具和库,广泛应用于图像识别、自然语言处理等领域。PyTorch:由Facebook开发的开源深度学习框架,…

JavaScript网页设计高级案例:构建交互式图片画廊

JavaScript网页设计高级案例:构建交互式图片画廊 在现代Web开发中,交互式元素已成为提升用户体验的关键因素。本文将通过一个高级案例 - 构建交互式图片画廊,展示如何结合HTML和JavaScript创建引人入胜的网页应用。这个案例不仅涵盖了基础的…

Linux命令大全:从入门到高效运维

适合人群:Linux新手 | 运维工程师 | 开发者 目录 一、Linux常用命令(每天必用) 1. 文件与目录操作 2. 文件内容查看与编辑 二、次常用命令(按需使用) 1. 系统管理与监控 2. 网络与通信 3. 权限与用户管理 三、…

Windows 10/11 使用 VSCode + SSH 免密远程连接 Ubuntu 服务器(指定端口)

摘要: 本文详细介绍如何在 Windows 系统上通过 VSCode Remote-SSH 免密登录远程 Ubuntu 服务器(SSH 端口 2202),避免每次输入密码的繁琐操作,提高开发效率。 1. 环境准备 本地系统:Windows 10/11远程服务…

一些需要学习的C++库:CGAL和Eysshot

写在前面: 从开始工作到现在,去过多家公司,多个行业, 虽然大部分时间在通信业,但也有其它的行业的工作没有做完,但也很感兴趣。每次想要研究一下时,总是想不起来。 这里写一些信息,…

蓝桥杯16天刷题计划一一Day01

蓝桥杯16天刷题计划一一Day01(STL练习) 作者:blue 时间:2025.3.26 文章目录 蓝桥杯16天刷题计划一一Day01(STL练习)[P1540 [NOIP 2010 提高组\] 机器翻译 - 洛谷 (luogu.com.cn)](https://www.luogu.com.…

相对位置2d矩阵和kron运算的思考

文章目录 1. 相对位置矩阵2d2. kron运算 1. 相对位置矩阵2d 在swin-transformer中,我们会计算每个patch之间的相对位置,那么我们看到有一连串的拉伸和相减,直接贴代码: import torch import torch.nn as nntorch.set_printoptio…

Redis 版本演进及主要新特性

Redis 版本发布历史 稳定版本时间线 Redis 2.6 (2012年)Redis 2.8 (2013年11月)Redis 3.0 (2015年4月) - 首次支持集群Redis 3.2 (2016年5月)Redis 4.0 (2017年7月)Redis 5.0 (2018年10月)Redis 6.0 (2020年4月)Redis 6.2 (2021年2月)Redis 7.0 (2022年4月) - 最新稳定版(截至…

HTML5 Geolocation(地理定位)学习笔记

一、HTML5 Geolocation简介 HTML5 Geolocation(地理定位)API用于获取用户的地理位置信息。通过这个API,可以获取用户的纬度、经度、海拔等信息。由于地理定位可能涉及用户隐私,因此只有在用户同意的情况下,才能获取其…

爱普生VG3225EFN压控晶振5G基站低噪声的解决方案

在 5G 通信网络的高速发展中,系统噪声的控制成为保障网络可靠性与数据吞吐量的关键。爱普生 VG3225EFN 压控晶振凭借其卓越的低噪声特性,成为 5G 基站时钟系统的理想选择。通过创新的技术设计,这款晶振不仅为基站提供了稳定的时钟基准&#x…

【问题解决】Linux安装conda修改~/.bashrc配置文件后,root 用户下显示 -bash-4.2#

问题描述 在Linux安装conda下的python环境时候,修改了~/.bashrc文件,修改完成后,再次进入服务器后,登录时候显示的不是正常的[rootlocalhost ~]#,而是-bash-4.2# 原因分析: 网上原因有:/root下…

机器学习knnlearn5

import numpy as np from os import listdir from sklearn.neighbors import KNeighborsClassifier as kNN# 此函数用于将一个32x32的文本文件转换为一个1x1024的一维向量 def img2vector(filename):"""将32x32的文本文件转换为1x1024的向量:param filename: 要…

git revert 用法实战:撤销一个 commit 或 merge

git revert 1 区别 • 常规的 commit (使用 git commit 提交的 commit) • merge commit 2 首先构建场景 master上的代码 dev开发分支上,添加一个a标签,并commit这次提交 切到master上,再次进行改动和提交 将de…