12、JVM高频面试题

1、JVM的主要组成部分有哪些

在这里插入图片描述

JVM主要分为下面几部分

  • 类加载器:负责将字节码文件加载到内存中

  • 运行时数据区:用于保存java程序运行过程中需要用到的数据和相关信息

  • 执行引擎:字节码文件并不能直接交给底层操作系统去执行,因此需要特定的命令解析器执行引擎将字节码翻译成底层系统指令

  • 本地库接口:会被执行引擎调用参与字节码的翻译

在这里面最主要的部分是运行时数据区,它又由五部分构成,分别是:堆、方法区、栈、本地方法栈、程序计数器

  • 堆是对象实例存储的主要区域
  • 方法区可以认为是堆的一部分,用于存储已被虚拟机加载的信息,比如常量、静态变量等等
  • 栈是程序方法运行的主要区域,栈里面存的是栈帧,栈帧里面存的是局部变量表、操作数栈、动态链接、方法出口等信息
  • 本地方法栈与栈功能相同,区别在于本地方法栈执行的是本地方法,即一个Java调用非Java代码的接口
  • 程序计数器主要存放的是当前线程所执行的字节码的行号,用于记录正在执行的字节码指令的地址

2、堆栈的区别是什么

堆和栈都是JVM的主要组成部分,不同点在于:

  • 栈内存一般会用来存储局部变量和方法调用,但堆内存是用来存储Java对象和数组的
  • 堆会GC垃圾回收,而栈不会
  • 栈内存是线程私有的,而堆内存是线程共有的
  • 两者异常错误不同,栈空间不足:java.lang.StackOverFlowError,堆空间不足:java.lang.OutOfMemoryError

3、JVM的类加载器有哪些

类加载器的主要作用就是将字节码文件加载到JVM中,从而让Java程序能够启动起来。根据各自加载范围的不同,主要划分为四种类加载器:

  • 启动类加载器(BootStrap ClassLoader):用于加载JAVA_HOME/jre/lib目录下的类库

  • 扩展类加载器(ExtClassLoader):用于加载JAVA_HOME/jre/lib/ext目录中的类库

  • 应用类加载器(AppClassLoader):用于加载classPath下的类,也就是加载开发者自己编写的Java类

  • 自定义类加载器:开发者自定义类继承ClassLoader,实现自定义类加载规则

4、什么是双亲委派模型

双亲委派模型是Java中的一种类加载机制。

在双亲委派模型中,类加载器之间形成了一种层次继承关系,从顶端开始依次是:启动类加载器->扩展类加载器->应用类加载器->自定义类加载器

当一个类加载器需要加载某个类时,它首先会委派给其上层类加载器去尝试加载该类。如果父类加载器无法加载该类,子类加载器才会尝试加载。

这种层次关系形成了一个从上到下的委派链。

双亲委派模型的主要目的是保证Java类的安全性和避免类的重复加载。当一个类加载器收到加载请求时,它会首先检查自己是否已经加载了该类。

如果已经加载,则直接返回该类的Class对象;如果未加载,则将加载请求委派给父类加载器。

父类加载器也会按照同样的方式进行检查,直到顶层的启动类加载器。如果顶层的启动类加载器无法加载该类,那么子类加载器会尝试自己加载。

这样可以避免同一个类被不同的类加载器加载多次,确保类的唯一性。

双亲委派模型的优势在于能够保证类的一致性和安全性。

通过委派链的机制,可以避免恶意代码通过自定义的类加载器加载替换系统核心类,从而提高了Java程序的安全性。

此外,通过双亲委派模型,可以实现类的共享和重用,减少内存占用和加载时间,提高了系统的性能。

5、说一下类加载器的执行过程

类从被加载到虚拟机内存中开始,直到卸载出内存为止,整个生命周期包括了7个阶段:加载、验证、准备、解析、初始化、使用、卸载

  1. 加载: 这个阶段会在内存中生成一个代表这个类的java.lang.Class对象
  2. 验证: 这个阶段的主要目的是为了确保Class文件包含的信息符合当前虚拟机的要求,并且不会危害虚拟机自身的安全
  3. 准备: 这个阶段正式为类变量分配内存并设置类变量的初始值,注意这里的初始值指的是默认值,而不是代码=后的实际值
  4. 解析: 这个阶段将符号引用替换为直接引用,比如方法中调用了其他方法,方法名可以理解为符号引用,而直接引用就是使用指针直接引用方法
  5. 初始化: 这个阶段是执行类构造器方法的过程,是类加载的最后一步,到了这一步Java虚拟机才开始真正执行类中定义的Java程序代码(字节码)
  6. 使用: 这个节点程序在运行
  7. 卸载: 这个阶段类Class对象被GC

在这里插入图片描述

6、怎么判断对象是否可以被回收

在堆中存放着几乎所有的对象实例,垃圾收集器在对堆进行回收前,第一件事就是要确定哪些对象是要回收的

JVM认为不被引用的对象就是可以被回收的对象,而它确认对象是否还在被引用的算法主要有两种:引用计数法和可达性分析算法

  1. 引用计数法

    在对象头处维护一个counter,每增加一次对该对象的引用,计数器自加,如果对该对象的引用失联,则计数器自减

    当counter为0时,表明该对象已经被废弃,不处于存活状态,

    但是此方法存在问题,假设两个对象相互引用始终无法释放counter,则永远不能GC

  2. 可达性分析算法

    通过一系列为GC Roots的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链

    当一个对象到GC Roots没有任何引用链相连时,则证明该对象是不可用的

    可以作为GC Roots的对象一般有栈中引用的对象 、方法区中类静态属性引用的对象以及

7、JVM的垃圾回收算法有哪些

目前JVM中的垃圾回收算法主要有四个,分别是:标记清除算法、标记-整理算法、复制算法和分代收集算法

  1. 标记清除算法是将垃圾回收分为2个阶段,分别是标记和清除

    它会先使用根据可达性分析算法找到垃圾资源进行标记,然后对这些标记为可回收的内容进行垃圾回收

    这种算法的主要不足有两个:

    • 效率问题,标记和清除阶段都要遍历多有对象,并且在GC时,需要停止应用程序,对于交互性要求比较高的应用而言这个体验是非常差的

    • 空间问题,对象被回收之后会产生大量不连续的内存碎片,当需要分配较大对象时,由于找不到合适的空闲内存而不得不再次触发垃圾回收动作

  2. 标记整理算法也是将垃圾回收分为2个阶段,分别是标记和整理清除

    它的第一阶段也是会先将存活的对象先标记出来

    不一样的地方在于第二阶段,它会将所有存活的对象向前移动放在一起,然后将无用空间回收,这样就会出现连续的可用空间了

    所以它解决了空间碎片问题,但是效率低的问题依旧存在

  3. 复制算法,将原有的内存空间一分为二,每次只用其中的一半

    在垃圾回收时,将正在使用的对象复制到另一个内存空间中,然后将当前内存空间清空,交换两个内存的角色,完成垃圾的回收。

    这种算法的缺点在于分配2块内存空间,在同一个时刻,只能使用一半,内存使用率较低

  4. 分代收集算法,它会将整个堆内存分成几部分空间,每个空间中放入不同类型的对象,然后各自适合的算法回收

    在JDK8时,堆被分为了两份:新生代和老年代,默认空间比例为1:2

    对于新生代,内部又被分为了三个区域:Eden区,S0区,S1区,,默认空间比例为8:1:1

在这里插入图片描述

它的基本工作机制是:

当创建一个对象的时候,这个对象会被分配在新生代的Eden区,当Eden区要满了时候,触发MinorGC

当进行MinorGC后,此时在Eden区存活的对象被移动到S0区,并且当前对象的年龄会加1,清空Eden区

当再一次触发MinorGC的时候,会把Eden区中存活下来的对象和S0中的对象,移动到S1区中,这些对象的年龄会加1,清空Eden区和S0区

当再一次触发YoungGC的时候,会把Eden区中存活下来的对象和S1中的对象,移动到S0区中,这些对象的年龄会加1,清空Eden区和S1区

对象的年龄达到了某一个限定的值(默认15岁),那么这个对象就会进入到老年代中,除此之外,大对象也会直接放入老年代空间

当老年代满了之后,触发FullGC**。**FullGC同时回收新生代和老年代

在上述过程中,新生代中的对象存活率比较低,所以选用复制算法;老年代中对象存活率高,所以使用标记-整理算法

小细节:

  1. 当对新生代产生GC:MinorGC,老年代代产生GC:Major GC ,新生代和老年代产生FullGC

  2. Minor GC非常频繁,一般回收速度也很快,Major GC一般会伴随一次Minor GC,Major GC的速度要慢很多,一般要比Minor GC慢10倍

  3. 占用内存较大的对象,对于虚拟机内存分配是一个坏消息,虚拟机提供了一个-XX:PretenureSizeThreshold让大于这个设置的对象直接存入老年代

  4. 虚拟机给每个对象定义了一个Age年龄计数器,对象在Eden中出生并经过第一次Minor GC后仍然存活,年龄+1,此后每熬过一次Minor GC则年龄+1,

当年龄增加到一定程度(默认15岁),就会晋升到老年代。可通过参数设置晋升年龄 -XX:MaxTenuringThreshold

8、JVM的垃圾回收器都有哪些

JVM中常见的一些垃圾回收器有:

  • 新生代回收器:Serial、ParNew、Parallel Scavenge

  • 老年代回收器:Serial Old、Parallel Old、CMS

  • 整堆回收器:G1

新生代垃圾回收器一般采用的是复制算法,复制算法的优点是效率高,缺点是内存利用率低

老年代回收器一般采用的是标记-整理的算法进行垃圾回收

  • List item

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

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

相关文章

DVWA-Hight-DOM型XSS漏洞

首先打开hight模块的DVWA,并来到DOM型XSS漏洞处 首先试探 这里普通的js代码被过滤 再利用img试探 同样被过滤 这里后端代码不太可能将所有可能利用黑名单的形式全部写入过滤代码中,所以这里后端的过滤代码大概率是白名单,也就是除了这个下拉列表中的名单…

【leetcode】力扣算法之相交链表【中等难度】

题目描述 给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null 。 图示两个链表在节点 c1 开始相交: 题目数据 保证 整个链式结构中不存在环。 注意,函数…

【Qt开发】PyQt6--标签控件

标签控件 Qlabel设置标签文本文本的对齐方式为标签设置超链接为标签设置图片获取标签文本 Qlabel QLabel标签控件,用于显示用户不能编辑的文本,主要起提示的作用 设置标签文本 文本的对齐方式 通过这可以设置文本对齐方式 为标签设置超链接 勾选以上…

竞赛保研 基于深度学习的人脸性别年龄识别 - 图像识别 opencv

文章目录 0 前言1 课题描述2 实现效果3 算法实现原理3.1 数据集3.2 深度学习识别算法3.3 特征提取主干网络3.4 总体实现流程 4 具体实现4.1 预训练数据格式4.2 部分实现代码 5 最后 0 前言 🔥 优质竞赛项目系列,今天要分享的是 🚩 毕业设计…

环境搭建 之 Ubuntu 安装

ubuntu-releases-20.04.6安装包下载_开源镜像站-阿里云ubuntu-releases-20.04.6安装包是阿里云官方提供的开源镜像免费下载服务,每天下载量过亿,阿里巴巴开源镜像站为包含ubuntu-releases-20.04.6安装包的几百个操作系统镜像和依赖包镜像进行免费CDN加速…

外汇天眼:放弃对波动的偏爱才能追逐趋势!

无论在熊市还是牛市中,市场上亏损者仍然和别的状态下一样多。 在趋势不明的情况下,我们盼望趋势的来临; 然而趋势真正形成之时,我们却仍然一无所获。 趋势表面上看对我们很重要,然而具体交易时却又难以利用,在具体交易…

乐理燥废笔记

乐理燥废笔记 文章目录 终止式小调音阶转调不协和和弦进行大小转调1251 1451转调我的霹雳猫阿诺三全音代理五声音阶又怎样和弦附录:压缩字符串、大小端格式转换压缩字符串浮点数压缩Packed-ASCII字符串 大小端转换什么是大端和小端数据传输中的大小端总结大小端转换…

IDEA中怎么用Postman?这款插件你试试

Postman是大家最常用的API调试工具,那么有没有一种方法可以不用手动写入接口到Postman,即可进行接口调试操作?今天给大家推荐一款IDEA插件:Apipost Helper,写完代码就可以调试接口并一键生成接口文档!而且还…

流式湖仓增强,Hologres + Flink 构建企业级实时数仓

流式湖仓增强,Hologres + Flink 构建企业级实时数仓 一、Hologres+Flink,阿里云上众多客户实时数仓的首选 随着大数据从规模化走向实时化,实时数据的需求覆盖互联网、交通、传媒、金融、政府等各个领域。实时计算在企业大数据平台的比重也在不断提高,部分行业已经达到了 50…

数环通12月产品更新:新增数据表相关功能、优化编辑器,15+应用进行更新

为了满足用户不断增长的需求,我们持续努力提升产品的功能和性能,以更好地支持用户的工作。 数环通12月的最新产品更新已经正式发布,带来了一系列强大的功能,以提升您的工作效率和系统的可靠性。 更新快速预览 新增&优化功能&a…

三维轮廓测量仪:革命性技术在工业智能制造中的多重应用

现代工业智能制造领域中,三维轮廓测量仪是一项重要的测量技术。三维轮廓测量仪利用光学、激光或光电等技术手段,通过测量物体表面轮廓的三维坐标信息,能实现对物体形状、尺寸和表面特征的准确测量。它可以广泛应用于工业自动化、制造工艺控制…

深入了解性能测试工具:优化应用性能的关键步骤

在当今数字化时代,应用程序性能是保持用户满意度和业务成功的关键因素之一。性能测试工具是开发和测试团队的宝贵资源,可以帮助识别和解决潜在的性能瓶颈,确保应用程序在各种负载条件下都能表现出色。本文将介绍性能测试工具的重要性、及它们…

Azkaban学习网站:大数据框架的一站式解决方案,让你事半功倍!

介绍:Azkaban是由LinkedIn公司推出的一个开源的任务调度系统,主要用于在一个工作流内按照特定的Azkaban是由LinkedIn公司推出的一个开源的任务调度系统,主要用于在一个工作流内按照特定的顺序运行一组工作和流程。它负责任务的调度运行&#…

如何进行深入的竞品分析:掌握这些技巧让你更加了解市场

随着互联网行业的快速发展,产品经理需要对竞品进行深入分析,才能更好地把握市场需求和趋势,为公司带来更好的商业价值。那么,如何做好竞品分析呢?以下是我对于这个问题的思考和建议。 一、确定分析的目的和范围 在开…

Nacos 学习之系列文章

系列文章目录 目录 系列文章目录 文章目录 前言 一、Nacos是什么? 二、Nacos的主要功能 服务发现和服务健康监测 动态配置服务 动态 DNS 服务 三、Nacos 地图 四、Nacos 生态图 总结 前言 Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。 Naco…

【稳定检索、投稿优惠】2024年航空航天工程与遥感科学技术国际会议(ICAERSST 2024)

2024年航空航天工程与遥感科学技术国际会议(ICAERSST 2024) 2024 International Conference on Aerospace Engineering and Remote Sensing Science and Technology(ICAERSST 2024) 一、【会议简介】 2024年,一场盛大的国际学术盛会航空航天工程与遥感科学技术国际会…

Spring中事务控制的API介绍(PlatformTransactionManager和TransactionDefinition)

什么是事务? 当你需要一次执行多条SQL语句时,可以使用事务。通俗一点说,如果这几条SQL语句全部执行成功,则才对数据库进行一次更新,如果有一条SQL语句执行失败,则这几条SQL语句全部不进行执行,…

【Python】不一样的Ansible(一)

不一样的Ansible——进阶学习 前言正文概念Ansible CorePlugins和Modules 插件插件类型编写自定义插件基本要求插件选项文档标准编写插件 添加一个本地插件注册为内置插件指定插件目录 其他一些技巧更改Strategy 结语 前言 Ansible 是一个极其简单的 IT 自动化引擎&#xff0c…

【洛谷学习自留】p9226 糖果

解题思路: 简单的计算题,用n对k取余,如果余数为0,则输出k的值,否则输出(k-余数)的值。 代码实现: import java.util.Scanner;public class p9226 {public static void main(Strin…

关于自增和自减的一些细节问题

目录 基本概念 1.运算 2.输出 基本概念 在这里简单回顾一下自增和自减:顾名思义,自就是同一变量的值发生变化,自增就是该变量值加1,自减就是该变量值减1。 自增和自减又可以根据运算符的位置不同分为前缀式和后缀式。前缀就是…