面试题分享之JVM篇

注意:文章若有错误的地方,欢迎评论区里面指正 🍭 

系列文章目录

  • 面试题分享之Java并发篇
  • 面试题分享之Java集合篇(二)

前言

学过Java的小伙伴肯定对JVM(Java虚拟机)多多少少了解一点,Java的“一次编译,到处运行”的特点就离不开他。今天我们就通过面试题去进一步的了解它。🌈


一、说一说你对JVM内存模型的理解

JVM内存区粗略的可以划分为堆和栈,按照虚拟机规范,又可分为一下几个区域:

 JVM内存分为线程私有区线程公共区。其中,堆内存和方法区属于线程公共区,虚拟机栈、本地方法区和程序计数器属于线程私有区,每个区的组成如上图所示。

 二、你知道Java对象的创建过程吗?

 我们大致可以分为六个过程:

  • 类加载:首先,JVM会从类路径中加载所需要创建的对象类,如果该类没有被加载,JVM会根据类的全限定名找到对应的字节码文件,并加载到内存里面去。

  • 分配内存:一旦类被加载之后,JVM会在堆中分配内存来存储实例数据,在堆中生成的内存地址作为对象的引用。
  • 初始化零值:在分配内存后,JVM会对分配的内存进行初始化。例如:对基本数据类型int初始化为零,引用数据类型初始化为null。
  • 设置对象头:在对象实例化之前,JVM会设置对象头,用于存储对象元信息,如:哈希码,GC信息等。对象头的大小由JVM的实现决定。
  • 执行构造函数:一旦对象的内存空间准备好,设置对象头完毕。JVM会根据构造函数来完成实例化。构造函数会对对象的实例字段进行初始化,可以执行其他必要的操作。
  • 返回对象引用:当构造函数执行完毕后,对象的状态就被完全初始化了。JVM会返回对象的引用,并赋值给变量,以便后续使用对象。

 🧑‍💼面试官追问:JVM创建对象时,堆会发生抢占吗?

有可能会。

  • 如果线程同时执行new操作创建对象时,理论上是存在可能发生堆的抢占情况的。如:假设线程A分配了一块内存,但是还没有发生指针的移动去实例化对象,这时候线程B也同时分配到这个内存,这个时候线程B的指针跟线程A的指针就会发生冲突。
  • 如果堆内存不足也会导致线程发生竞争抢占。JVM在堆不足时,会触发垃圾回收去清理不使用的对象,把内存空间给新的对象分配。

 🧑‍💼面试官继续追问:如何解决堆抢占这个问题呢?

  • 采用CAS分配重试的方法来保证更新的原子性。
  • 每个线程在Java堆中预先分配一小块内存,也就是本地线程分配缓冲,要分配内存的线程,现在本地缓冲区中分配,只有本地缓冲区用完了,才回去锁定新的后缓存区。

三、如何判断对象仍然存活?(如何判断对象需要被回收?)

判断对象存活一般有两种方法

  • 引用计数法:该方法通过对对象进行引用计数,每次对象时计数加1,当引用计数为0时,表示没有被引用,可以被回收。但是引用技术法无法解决循序引用的问题,导致内存泄漏。
  • 可达性分析法:常见的垃圾回收算法中,主要采用的可达性分析算法。该算法从一组成为“根”的特定对象(如全局变量活动线程等)开始,通过追踪对象之间的引用关系形成引用图,然后检查哪些对象可以从“根”对象访问到。如果一个对象可以从“根”对象访问到,那么它就会被认为是存活的。而对于无法从“根”对象访问到的对象,则被判断为不在存活,垃圾回收器将其进行回收。

 🧑‍💼面试官追问:垃圾算法了解吗?

  • 标记-清除算法:该算法通过标记对象的可达性来确定对象存活,清除未标记的对象。这种算法虽然零活,但是可能会产生内存碎片。
  • 标记-复制算法:该算法需要额外的内存区,将正在使用的内存区里面存活的对象进行标记,然后复制到新的缓存区里面。缺点:需要额外的内存区来保存复制对象,与其他算法比,有一定的内存浪费。
  • 标记-整理算法:该算法首先标记存活的对象,然后将他们紧凑的排列到内存区的一端,清除未标记的对象。缺点:需要进行对象移动的操作,可能增加垃圾回收的时间消耗。
  • 分代回收算法:该算法根据对象的生命周期将内存分为不同的区。新创建的对象会分到新生代,经过多次回收仍然存活的对象会晋升到老年代。不同带使用不同的垃圾回收策略,以提高效率。
    • ​​​​​​新生代:每次都有大量对象消亡,因为有老年代作为内存担保,通常采用复制算法。
    • 老年代:对象存活时间长,可采用标记清除、标记整理算法。

四、能详细说一下CMS收集器的垃圾收集过程吗?

CMS(Concurrent Mark Sweep)收集器:是一种以获取最短回收停顿时间为目标的收集器。它主要针对响应时间敏感的应用程序,并通过执行大部分垃圾收集工作来减少停顿时间。

CMS收集器的垃圾收集过程主要分为五个阶段:

收集流程:

  • 初始标记:暂停所有其他线程,记录直接与root连接的对象,速度很快
  • 并发标记:同时开启GC和用户线程,使用一个闭包结构去记录可达对象。但是在这个阶段结束后,这个闭包结构并不能保证当前所有对象可达,因为用户线程会不断的更新引用域,所以GC线程无法保证可达性分析的实时性。这个算法作用就是跟踪记录这些发生引用更新的地方。
  • 重新标记:作用是修正并发标记时因为用户程序而导致标记变更的那一部分对象的标记记录,这个阶段的停顿时间比初始标记时间长,但是远远比并发标记时间短。
  • 并发清除:开启用户线程后,同时GC线程开始对未标记的区域做清扫。

五、G1垃圾收集器了解吗?

G1垃圾收集器的设计目标是在停顿时间可控的情况下,最大化系统吞吐量,它旨在提供更可控、更高效的垃圾回收性能。

 

  • 面向服务器的垃圾收集器,极高概率满足GC停顿时间和吞吐量有要求。
  • 并行与并发:可以充分利用CPU、多核环境下的硬件优势,使用多个CPU(CPU或者核心)来缩短stop-the-world停顿时间。部分其他收集器原本需要停顿Java线程执行GC,但是G1仍然可以通过并发的方式让Java程序继续执行。
  • 分代收集:不需要和其他收集器配合,自己使用分代收集。
  • 混合回收:同时处理新生代和老年代的垃圾回收,相比于传统的分代回收,它可以均衡的处理整个堆内存,避免长时间的Full GC暂停。
  • 可预测的停顿:G1的一个大优势,G1除了追求低停顿外,还能建立可预测的时间模型,能让使用者明确指定在一个长度为 M 毫秒的时间片段内,消耗在垃圾收集上的时间不得超过 N 毫秒。

六、说一下尽量避免内存泄漏的方法?

  • 尽量不要使用 static 成员变量,减少生命周期;
  • 及时关闭无用的资源
  • 不用的对象,可以手动设置为 null

七、谈谈你对类加载机制的了解? 

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

  • 加载:查找并加载类的二进制数据
  • 验证:确保被加载的类的正确性
  • 准备:为类的静态变量分配内存,并将其初始化为默认值
  • 解析:把类中的符号引用转换为直接引用
  • 初始化:为类的静态变量赋予正确的初始值,JVM负责对类进行初始化,主要对类变量进行初始化

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

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

相关文章

工程项目管理系统:高效、专业的工程管理软件

在当今快速发展的工程行业,有效的项目管理是确保项目成功的关键。鸿鹄工程项目管理系统,基于Spring Cloud、Spring Boot、Mybatis、Vue和ElementUI技术栈,提供了一个全面、高效的解决方案,以应对复杂的工程项目管理挑战。 项目背景…

ChatGLM3-6B-32K 在linux(Ubuntu) GPU P100(16G)复现记录

ChatGLM3-6B-32K 在linux(Ubuntu) GPU P100(16G)复现记录 时间:2024年6月12日 1.创建Conda环境 conda create --name chatglm3 python3.10 conda activate chatglm32.下载chatglm,并安装依赖 如果没有安装git命令,先安装git命令 sudo ap…

开展文化科技卫生“三下乡”活动怎样向媒体投稿宣传?

在新时代背景下,“文化科技卫生三下乡”活动作为推动乡村振兴、促进城乡融合发展的重要举措,正发挥着不可小觑的作用。这类活动通过输送文化、科技、卫生等领域的资源和服务到农村,极大地丰富了农民的精神生活,提升了农村的科学素…

【目标检测】基于深度学习的车牌识别管理系统(含UI界面)【python源码+Pyqt5界面 MX_002期】

系统简介: 车牌识别技术作为经典的机器视觉任务,具有广泛的应用前景。通过图像处理方法,车牌识别技术能够对车牌上的字符进行检测、定位和识别,从而实现计算机对车牌的智能化管理。在现实生活中,车牌识别系统已在小区停…

前端传递bool型后端用int收不到

文章目录 背景模拟错误点解决方法 背景 我前几天遇到一个低级错误,就是我前端发一个请求,把参数送到后端,但是我参数里面无意间传的布尔型(刚开始一直没注意到,因为当时参数有十几个),但是我后…

认证体系下的CID广告服务商:构建商家与服务商的共赢生态

摘要:引流电商服务商认证体系的构建促进了商家与服务商之间的顺畅合作,降低了风险,优化了资源配置。认证提升了服务商形象,扩大了市场份额,推动了行业技术创新和服务升级,构建了共赢生态。 在引流电商行业…

发布会后苹果股价创历史新高;商汤 Embedding 模型拿下 SOTA丨 RTE 开发者日报 Vol.223

开发者朋友们大家好: 这里是 「RTE 开发者日报」 ,每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享 RTE(Real-Time Engagement) 领域内「有话题的 新闻 」、「有态度的 观点 」、「有意思的 数据 」、「有思考的 文…

免密支付存隐患 谨防“便捷”变“踩坑”

免密支付存隐患 谨防“便捷”变“踩坑” 当前,我国网购用户已超9亿人,越来越便捷的支付手段让网络消费体验更加“丝滑”。但免密支付、自动续费等方式在简化付款流程的同时,也成为一些平台“套路”消费者的手段,暗藏诱导消费陷阱。…

闪烁与常亮的符号状态判断机制(状态机算法)

背景说明 在视觉项目中,经常要判断目标的状态,例如:符号的不同频率闪烁、常亮等。然而常规的视觉算法例如YOLO,仅仅只能获取当前帧是否存在该符号,而无法对于符号状态进行判断,然而重新写一个基于时序的卷积…

跟着AI学AI_09 PyTorch 简介

PyTorch 简介 PyTorch 是一个开源的深度学习框架,由 Facebook 的人工智能研究团队(FAIR)开发。它提供了灵活且高效的张量计算功能,并支持动态计算图。PyTorch 的易用性和灵活性使其成为深度学习研究和生产应用中广泛使用的工具。…

一维、二维数组练习题

1、输入一个6个元素的一维数组,实现冒泡排序 2、输入一个6个元素的一维数组,实现简单排序 3、输入一个5个元素的一维数组,求最大值,最小值 4、输入一个三行四列的二维数组,计算最大值和最小值

期权和股票有什么区别?

今天带你了解期权和股票有什么区别?股票和期权都是投资产品,但它们却是两种截然不同的交易模式,在开户要求上也有很多差别。 期权和股票有什么区别? 权利与义务: 股票:代表公司的所有权的一部分&#xff…

【扫码点餐系统】制作搭建部署

前言: 餐饮类做一个扫码点餐的工具可以提升用户体验、扩大市场份额、提高运营效率以及适应数字化趋势等方面。 一、企业开发小程序原因 企业开发小程序具有多方面的优势,可以帮助企业提升用户体验、扩大市场份额、提高运营效率以及适应数字化趋势等。…

线程安全问题【snychornized 、死锁、线程通信】

目录 一、线程安全1.1 线程安全问题?1.2 如何解决线程安全问题方法具体如何实现? 1.3 同步方法1.4 同步代码块1.5 总结1.6 售票例子1.8 补充 二、线程安全的集合三、死锁【了解】四、线程通信4.1 同步方法4.2 同步代码块4.3 wait和sleep本篇的思维导图 最后 一、线程安全 1.…

批量替换删除图片文件名称中相同数字:轻松管理文件结构新技巧大揭秘

特别是当图片文件名称中包含相同的数字时,想要快速找到或整理这些文件更是难上加难。今天,我要向大家揭秘一种轻松管理图片文件结构的新软件——文件批量改名高手。 进入“文件批量改命名高手”主页面,你会看到一个简洁明了的操作界面。在板…

【Linux】模拟实现一个简单的日志系统

👦个人主页:Weraphael ✍🏻作者简介:目前正在学习c和算法 ✈️专栏:Linux 🐋 希望大家多多支持,咱一起进步!😁 如果文章有啥瑕疵,希望大佬指点一二 如果文章对…

C++ 11 之 参数传递

c11参数传递.cpp #include <iostream> using namespace std;void swap1(int a, int b) {int temp a;a b;b temp;cout << "函数的a: " << a << endl;cout << "函数的b: " << b << endl; }void swap2(int *a,…

Boost-PFC电路讲解

电路拓扑图 PFC_Boost与普通Boost的区别 普通Boost&#xff1a;通常是用一次电源的输出的直流来作为它的输入&#xff0c;输入电压比较稳定&#xff0c;无需考虑 PF值THD方面的东西 PFC_Boost&#xff1a;直接是市电输入&#xff0c;输入电压是电压大小和方向时刻在变化的正弦…

AI日报|苹果生态全面整合AI功能,字节跳动被曝秘密启动AI手机研发

文章推荐 粽叶飘香&#xff0c;端午安康&#xff01;AI视频送祝福啦~ 谁是最会写作文的AI“考生”&#xff1f;“阅卷老师”ChatGPT直呼惊艳&#xff01; ⭐️搜索“可信AI进展“关注公众号&#xff0c;获取当日最新AI资讯 苹果WWDC 2024&#xff1a;AI为苹果带来了什么&am…

Linux基础之进程替换

目录 一、进程替换的基本概念 二、exec系列函数 2.1 execl系列函数 2.2 execv系列函数 2.3 替换原理 一、进程替换的基本概念 根据我们之前所学&#xff0c;我们可以知道我们所创建的所有的子进程&#xff0c;执行的代码&#xff0c;都是父进程代码的一部分。如果我们想让…