Java面试题、八股文学习之JVM篇

news2024/11/28 1:49:26

1.对象一定分配在堆中吗?有没有了解逃逸分析技术?

对象不一定总是分配在堆中。在Java等一些高级编程语言中,对象的分配位置可以通过编译器或运行时系统的优化来决定。其中,逃逸分析(Escape Analysis)是用于提高程序性能的一种技术,它可以帮助JVM(Java虚拟机)确定一个对象是否真的需要被分配到堆上。

逃逸分析的基本概念

逃逸分析是一种可以确定指针动态范围的技术。如果一个对象在一个方法内部创建,并且这个对象的引用不会逃逸出该方法(即该方法之外的代码无法访问这个对象),那么这个对象就可以被认为是“不逃逸”的。反之,如果一个对象的引用可以被其他线程访问或者存储到全局变量中,那么这个对象就是“逃逸”的。

逃逸分析的应用

  • 栈上分配:对于不逃逸的对象,JVM可以选择不在堆上分配内存,而是在栈上分配。这样做可以减少垃圾回收的压力,因为栈上的对象会随着方法的结束而自动销毁。这种方法也被称为“栈分配”。

  • 同步消除:如果一个对象只被一个线程访问,那么对该对象的同步操作(如锁)可能是不必要的。通过逃逸分析,JVM可以识别这些情况并移除多余的同步开销。

  • 标量替换:当一个对象的所有字段都不会逃逸时,JVM可以直接将这些字段分配给调用者的方法栈帧,而不需要为整个对象分配空间。这进一步减少了内存的使用和垃圾回收的工作量。

实现细节

逃逸分析的具体实现依赖于具体的JVM版本和配置。例如,在HotSpot JVM中,默认情况下逃逸分析是开启的,但它的效果可能会受到其他因素的影响,比如JIT(Just-In-Time)编译器的选择和优化级别。

总的来说,逃逸分析是一个强大的工具,它可以显著提升应用程序的性能,尤其是在内存管理和多线程环境中。然而,它的效果并不是绝对的,有时候可能需要开发者通过代码设计来辅助优化。

2.虚拟机为什么使用元空间替换了永久代?

Java虚拟机(JVM)在Java 8及更高版本中,使用元空间(Metaspace)替换了永久代(PermGen),主要是为了改进内存管理的效率和灵活性。以下是几个关键原因:

  • 无固定大小限制:永久代有一个固定的大小,当加载大量的类时可能会导致OutOfMemoryError。而元空间是动态扩展的,默认情况下不受JVM堆大小的限制,只受限于操作系统的可用内存。
  • 性能优化:移除永久代后,类的元数据存储在本地内存区域,这有助于提高垃圾回收的效率。由于类的元数据不再与应用程序对象一起存储在堆中,因此可以更有效地进行清理和压缩。
  • 简化内存管理:永久代的设计初衷是为了隔离类的元数据和其他应用程序数据,但它的实现较为复杂。相比之下,元空间通过直接使用本地内存来简化了内存管理过程。
  • 更好的诊断工具支持:随着元空间的引入,相关的监控和调试工具得到了增强,能够更好地帮助开发者理解和解决与类加载相关的问题。
  • 减少碎片化:永久代容易产生碎片化问题,尤其是在频繁加载和卸载类的情况下。元空间则避免了这种问题,因为它不依赖于堆内存分配策略。

这些改进使得元空间成为了一个更为高效、灵活和可靠的替代方案。

3.什么是Stop The World ? 什么是OopMap?什么是安全点?

在Java虚拟机(JVM)中,Stop-The-World (STW)、OopMap 和 安全点(Safepoint) 是与垃圾回收和其他并发操作密切相关的重要概念。下面我将详细解释每个概念及其作用。

Stop-The-World (STW)

Stop-The-World 指的是 JVM 在执行某些操作时需要暂停所有正在运行的 Java 线程。这些操作通常包括但不限于:

  • Full GC(Full Garbage Collection):当年轻代和老年代都需要进行垃圾回收时。
  • Heap Resize:调整堆内存大小。
  • Class Unloading:卸载不再使用的类。
  • Thread Dumping:生成线程转储信息。
  • Debugging Operations:调试操作。

特点

  • 暂停时间:STW 会导致所有 Java 线程暂停,这段时间称为 STW 停顿。
  • 影响性能:长时间的 STW 停顿会影响应用程序的响应时间和吞吐量。
  • 优化目标:现代 JVM 实现通过各种技术(如 G1 垃圾收集器)尽量缩短 STW 时间。

OopMap

OopMap 是一种数据结构,用于记录某个时刻线程栈上对象引用的位置。它在垃圾回收过程中扮演着关键角色,特别是在处理并发垃圾回收算法时。

主要用途:

  • 识别活动对象:在垃圾回收期间,GC 需要知道哪些对象仍然被程序引用,以决定是否可以回收它们。OopMap 提供了这些对象的精确位置信息。
  • 支持增量式和并发垃圾回收:通过 OopMap,GC 可以准确地跟踪和更新对象引用,即使是在线程继续运行的情况下也能进行有效的垃圾回收。

安全点(Safepoint)

  • 安全点是指程序执行过程中的特定位置,在这些位置,所有的线程都可以被暂停,并且此时的程序状态是“一致”的。换句话说,安全点是一个可以让 JVM 进行全局操作的时间点,比如垃圾回收。

关键特性:

  • 一致的状态:在安全点处,所有的线程都处于一个可预测的状态,便于 JVM 执行全局操作。
  • 自动插入:编译器会在字节码中自动插入安全点指令,通常在方法调用、循环控制等地方。
  • 协作机制:线程在遇到安全点时会检查是否有全局操作请求,如果有,则进入等待状态,直到操作完成。

安全点与 OopMap 的关系

安全点和 OopMap 之间有着密切的关系:

  • 同步信息:在安全点处,线程会提供其当前的 OopMap 给垃圾回收器,以便 GC 能够准确地追踪和更新对象引用。
  • 协调操作:通过结合安全点和 OopMap,JVM 可以在不中断应用程序逻辑的前提下高效地执行垃圾回收和其他全局操作。

总结

  • Stop-The-World:JVM 暂停所有线程以执行全局操作,常见于 Full GC。
  • OopMap:记录线程栈上的对象引用位置,帮助垃圾回收器识别活动对象。
  • 安全点:程序执行过程中的特定位置,允许 JVM 暂停所有线程并执行全局操作。

4.说一下JVM 的主要组成部分及其作用?

Java虚拟机(JVM)是Java平台的核心组件,负责执行编译后的Java字节码。JVM由多个主要组成部分构成,每个部分都有其特定的作用。以下是JVM的主要组成部分及其作用:

1. 类加载器子系统 (ClassLoader Subsystem)

作用:

  • 加载类:从不同的来源(如文件系统、网络等)加载类文件。
  • 链接类:包括验证、准备和解析三个阶段。
    • 验证:确保加载的类符合JVM规范。
    • 准备:为类的静态变量分配内存,并设置默认初始值。
    • 解析:将常量池中的符号引用替换为直接引用。
  • 初始化类:执行类构造器 () 方法,对静态变量进行显式初始化。

2. 运行时数据区 (Runtime Data Areas)

作用:

  • 方法区 (Method Area):存储类的信息(如字段、方法)、常量池、静态变量等。在Java 8及更高版本中,方法区被元空间(Metaspace)取代。
  • 堆 (Heap):所有线程共享的一块内存区域,用于存储对象实例和数组。
  • Java栈 (Java Stack):每个线程拥有一个私有的Java栈,用于存储方法调用帧(Frame),每个帧包含局部变量表、操作数栈、动态链接信息等。
  • 程序计数器 (Program Counter Register):每个线程有一个程序计数器,指向当前正在执行的指令。
  • 本地方法栈 (Native Method Stack):用于支持本地方法(C/C++ 编写的代码)的执行。

3. 执行引擎 (Execution Engine)

作用:

  • 解释器 (Interpreter):逐条解释字节码指令,适用于启动初期或方法调用次数较少的情况。
  • 即时编译器 (Just-In-Time Compiler, JIT Compiler):将热点代码(频繁执行的方法)编译成机器码,提高执行效率。常见的JIT编译器有HotSpot VM中的Client Compiler和Server Compiler。
  • 垃圾回收器 (Garbage Collector):自动管理内存,回收不再使用的对象,防止内存泄漏。

4. 系统接口 (System Interface)

作用:

  • 本地接口 (Native Interface):提供与操作系统之间的通信机制,允许Java程序调用本地库函数。
  • 输入输出接口 (Input/Output Interface):处理标准输入输出流,以及文件系统访问等。

5. 工具接口 (Tool Interface)

作用:

  • 调试接口 (Debugging Interface):提供调试功能,允许开发者使用调试工具检查和控制程序运行状态。
  • 性能监控接口 (Performance Monitoring Interface):提供性能监控功能,帮助开发者分析和优化程序性能。

6. 安全管理器 (Security Manager)

作用:

  • 安全管理:控制程序的行为,防止恶意代码对系统造成损害。通过安全策略文件定义权限规则。

7. 内核类库 (Core Class Libraries)

作用:

  • 提供丰富的API:包括集合框架、I/O处理、多线程支持、图形用户界面等,简化开发工作。

总结

JVM 的各个组成部分协同工作,共同实现了 Java 字节码到机器码的转换和执行过程,提供了高效的运行环境。了解这些组成部分及其作用有助于更好地理解和优化 Java 应用程序的性能和安全性。

5.什么是指针碰撞?

指针碰撞(Pointer Bumping) 是一种内存分配策略,主要用于堆内存管理。它通常与 分代垃圾回收(Generational Garbage Collection) 结合使用,特别是在年轻代的内存分配中。下面详细介绍指针碰撞的工作原理及其特点。

指针碰撞的基本概念

在分代垃圾回收机制中,堆内存被分为不同的区域,最常见的是 年轻代(Young Generation) 和 老年代(Old Generation)。年轻代进一步细分为 Eden 区 和两个 Survivor 区(通常是 S0 和 S1)。指针碰撞主要发生在 Eden 区和 Survivor 区的内存分配过程中。

工作原理

  • 初始化:

    • 当 JVM 启动时,年轻代会被划分为 Eden 区和两个 Survivor 区。
    • 初始化时,top 指针指向 Eden 区的起始位置,end 指针指向 Eden 区的末尾。
  • 对象分配

    • 当需要创建新对象时,JVM 会尝试将对象分配到 Eden 区。
    • 分配过程非常简单且高效:只需移动 top 指针,使其向前移动对象所需的字节数。这个操作类似于“指针碰撞”。
  • 检查空间

    • 在每次分配对象之前,JVM 会检查 Eden 区是否有足够的连续空间来容纳新对象。
    • 如果有足够的空间,则直接进行指针碰撞;否则,触发 Young GC 或者重新分配 Survivor 区的空间。
  • Minor GC(Young GC)

    • 当 Eden 区满载或即将满载时,发生 Minor GC。
    • 尚存活的对象会被复制到其中一个 Survivor 区(例如 S0),而另一个 Survivor 区(S1)则清空。
    • 生存下来的对象在下次 Minor GC 中可能会再次被复制到另一个 Survivor 区,或者如果达到一定的年龄阈值(通常是 15 次),则会被晋升到老年代。
  • 指针重置

    • Minor GC 后,top 指针会重置回 Eden 区的起始位置,准备接收新的对象分配。

示例图解

假设有一个简单的年轻代结构如下:

+-------------------+
|       Eden        |
|                   |
|      top          | -> 指向下一个可用地址
|                   |
+-------------------+
|     Survivor S0   |
+-------------------+
|     Survivor S1   |
+-------------------+

初始状态:

+-------------------+
|       Eden        |
|                   |
|      top          | -> 初始位置
|                   |
+-------------------+
|     Survivor S0   |
+-------------------+
|     Survivor S1   |
+-------------------+

分配对象 A:

+-------------------+
|       Eden        |
|       [A]         |
|      top          | -> 移动后的 top
|                   |
+-------------------+
|     Survivor S0   |
+-------------------+
|     Survivor S1   |
+-------------------+

分配对象 B:

+-------------------+
|       Eden        |
|       [A][B]       |
|      top          | -> 再次移动后的 top
|                   |
+-------------------+
|     Survivor S0   |
+-------------------+
|     Survivor S1   |
+-------------------+

触发 Minor GC

  • 存活对象 [A] 被复制到 S0。
  • Eden 和 S1 清空。
  • top 指针重置到 Eden 的起始位置。

GC 后的状态:

+-------------------+
|       Eden        |
|                   |
|      top          | -> 初始位置
|                   |
+-------------------+
|     Survivor S0   |
|       [A]         |
+-------------------+
|     Survivor S1   |
+-------------------+

特点和优势

  • 高效性:
    • 指针碰撞只需要简单的指针移动操作,速度极快,适合频繁的对象分配场景。
  • 低开销:
    • 相比于其他复杂的内存分配算法,指针碰撞几乎没有额外的开销。
  • 紧凑存储:
    • 新分配的对象紧邻在一起,减少了内存碎片化的问题。
  • 易于实现:
    • 指针碰撞的逻辑相对简单,易于理解和实现。

注意事项

  • 内存不足:
    • 如果 Eden 区无法容纳新对象,需要触发 Minor GC 或者调整堆大小。
  • 对象过大:
    • 对于大对象(大于 Eden 区一半大小的对象),通常会直接分配到老年代,以避免频繁的 GC。
  • 垃圾回收频率:
    • 频繁的对象分配可能导致较高的 Minor GC 频率,影响性能。可以通过调整堆大小和垃圾收集器参数来优化。

总结

指针碰撞是一种高效的内存分配策略,广泛应用于现代 JVM 的年轻代内存管理中。通过简单的指针移动操作,它可以快速地为新对象分配内存,并结合分代垃圾回收机制有效地管理内存,确保应用程序的高性能和稳定性。

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

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

相关文章

微信小程序2-地图显示和地图标记

一、index修改页面&#xff0c;让页面能够显示地图和一个添加标记的按钮。 index.wxml <scroll-view class"scrollarea" scroll-y type"list"><view class"index_container"><map id"map" style"width: 100%; h…

【C++】从C语言到C++学习指南

如果你也是从C语言一路过来的&#xff0c;那么请一起看下去吧&#xff01; 文章目录 面型对象程序设计C基础C和C一些语法区别C在非对象方面对C语言的扩充C的一些标准&#xff08;兼容旧标准&#xff09; 首先&#xff0c;在C的学习中&#xff0c;我们要时刻清醒一点&#xff1…

Fakelocation Server服务器/专业版 ubuntu

前言:需要Ubuntu系统 Fakelocation开源文件系统需求 Ubuntu | Fakelocation | 任务一 任务一 更新Ubuntu&#xff08;安装下载不再赘述&#xff09; sudo -i # 提权 sudo apt update # 更新软件包列表 sudo apt upgrade # 升级已安装的软…

探索Python的HTTP之旅:揭秘Requests库的神秘面纱

文章目录 **探索Python的HTTP之旅&#xff1a;揭秘Requests库的神秘面纱**第一部分&#xff1a;背景介绍第二部分&#xff1a;Requests库是什么&#xff1f;第三部分&#xff1a;如何安装Requests库&#xff1f;第四部分&#xff1a;Requests库的五个简单函数使用方法第五部分&…

WPF——ICON按钮制作

前言 首先ICON按钮&#xff0c;即带图标按钮&#xff0c;即图标按钮。 图标按钮在开发时&#xff0c;主要是有两种方式来进行。一是在Button的Content内添加Image&#xff0c;然后设置Image的属性Source来实现&#xff0c;这种方式主要是简单易操作&#xff0c;对于初学者来说…

【MySQL篇】持久化和非持久化统计信息的深度剖析(第一篇,总共六篇)

&#x1f4ab;《博主介绍》&#xff1a;✨又是一天没白过&#xff0c;我是奈斯&#xff0c;DBA一名✨ &#x1f4ab;《擅长领域》&#xff1a;✌️擅长Oracle、MySQL、SQLserver、阿里云AnalyticDB for MySQL(分布式数据仓库)、Linux&#xff0c;也在扩展大数据方向的知识面✌️…

三开关VUE组件

一、使用效果 <template><QqThreeSwitch v-model"value" /><!-- <SqThreeSwitch v-model"value" :options"[test1, test2, test3]"><template #left-action><div style"display: flex"><IconMoon…

线段树与树状数组 (C++)

线段树&#xff1a;基于分治思想的二叉树&#xff0c;用于维护区间信息&#xff08;区间和&#xff0c;区间最值等&#xff09;&#xff0c;区间修改和区间查询的时间复杂度为logn 叶子节点存储元素本身&#xff0c;非叶子节点存取区间信息 1.节点&#xff1a;是一个结构体&a…

vue3 uniapp 扫普通链接或二维码打开小程序并获取携带参数

vue3 uniapp 扫普通链接或二维码打开小程序并获取携带参数 微信公众平台添加配置 微信公众平台 > 开发管理 > 开发设置 > 扫普通链接二维码打开小程序 配置链接规则需要下载校验文档给后端存入服务器中&#xff0c;保存配置的时候会校验一次&#xff0c;确定当前的配…

数据结构(初阶6)---二叉树(遍历——递归的艺术)(详解)

二叉树的遍历与练习 一.二叉树的基本遍历形式1.前序遍历(深度优先遍历)2.中序遍历(深度优先遍历)3.后序遍历(深度优先遍历)4.层序遍历&#xff01;&#xff01;(广度优先遍历) 二.二叉树的leetcode小练习1.判断平衡二叉树1&#xff09;正常解法2&#xff09;优化解法 2.对称二叉…

spring boot2.7集成OpenFeign 3.1.7

1.Feign Feign是一个声明式web服务客户端。它使编写web服务客户端更容易。要使用Feign&#xff0c;请创建一个接口并对其进行注释。它具有可插入注释支持&#xff0c;包括Feign注释和JAX-RS注释。Feign还支持可插拔编码器和解码器。Spring Cloud增加了对Spring MVC注释的支持&…

基于Redis内核的热key统计实现方案|得物技术

一、Redis热key介绍 Redis热key问题是指单位时间内&#xff0c;某个特定key的访问量特别高&#xff0c;占用大量的CPU资源&#xff0c;影响其他请求并导致整体性能降低。而且&#xff0c;如果访问热key的命令是时间复杂度较高的命令&#xff0c;会使得CPU消耗变得更加严重&…

CTF-Hub SQL 报错注入(纯手动注入)

​ 当输入1时&#xff0c;发现只有查询正确&#xff0c;基本上可以判断出没有回显 开始注入(工具hackerBar) 题目是报错注入&#xff0c;方向就比较明显&#xff0c;大致说一下用到的函数和原理。 常见报错注入函数&#xff1a; 通过 floor() 报错注入通过 extractValue() …

Elasticsearch中的节点(比如共20个),其中的10个选了一个master,另外10个选了另一个master,怎么办?

大家好&#xff0c;我是锋哥。今天分享关于【Elasticsearch中的节点&#xff08;比如共20个&#xff09;&#xff0c;其中的10个选了一个master&#xff0c;另外10个选了另一个master&#xff0c;怎么办&#xff1f;】面试题。希望对大家有帮助&#xff1b; Elasticsearch中的节…

linux安装mysql8.0.40

一、下载MySQL安装包 1.查看glibc版本 rpm -qa | grep glibc 2.到mysql官网下载安装包 ​ 二、解压安装 1.上传压缩包纸/usr/local 目录下&#xff0c;解压&#xff1a; tar -xvf mysql-8.0.40-linux-glibc2.17-x86_64.tar.xz 2.重命名&#xff1a; mv mysql-8.0.40-linux-…

【大数据学习 | Spark-Core】RDD的五大特性(包含宽窄依赖)

分析一下rdd的特性和执行流程 A list of partitions 存在一系列的分区列表A function for computing each split 每个rdd上面都存在compute方法进行计算A list of dependencies on other RDDs 每个rdd上面都存在一系列的依赖关系Optionally, a Partitioner for key-value RDDs…

在 Taro 中实现系统主题适配:亮/暗模式

目录 背景实现方案方案一&#xff1a;CSS 变量 prefers-color-scheme 媒体查询什么是 prefers-color-scheme&#xff1f;代码示例 方案二&#xff1a;通过 JavaScript 监听系统主题切换 背景 用Taro开发的微信小程序&#xff0c;需求是页面的UI主题想要跟随手机系统的主题适配…

【C语言】int *p[ ] 与 int (*p)[ ] 的区分辨析

博客主页&#xff1a; [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C语言 文章目录 &#x1f4af;前言&#x1f4af;基本概念&#xff1a;数组与指针&#x1f4af;理解 int *p[10] 与 int (*p)[10]1. int *p[10]&#xff1a;存放指针的数组2. int (*p)[10]&#xff1a;指向数组的指针 …

Vue3 el-table 默认选中 传入的数组

一、效果&#xff1a; 二、官网是VUE2 现更改为Vue3写法 <template><el-table:data"tableData"border striperow-key"id"ref"tableRef":cell-style"{ text-align: center }":header-cell-style"{background: #b7babd…

MT6769/MTK6769核心板规格参数_联发科安卓主板开发板方案

MT6769安卓核心板具有集成的蓝牙、FM、WLAN和GPS模块&#xff0c;是一个高度集成的基带平台&#xff0c;结合了调制解调器和应用处理子系统&#xff0c;以支持LTE/LTE-A和C2K智能手机应用。 该芯片集成了两个工作频率高达2.0GHz的ARMCortex-A75内核、六个工作频率高达1.70GHz的…