面试 JVM 八股文五问五答第一期

面试 JVM 八股文五问五答第一期

作者:程序员小白条,个人博客

相信看了本文后,对你的面试是有一定帮助的!

⭐点赞⭐收藏⭐不迷路!⭐

1.JVM内存布局

Heap (堆区)

堆是 OOM 故障最主要的发生区域。它是内存区域中最大的一块区域,被所有线程共享,存储着几乎所有的实例对象、数组。

Java 堆是垃圾收集器管理的主要区域,因此很多时候也被称做“GC 堆”。从内存回收的角度来看,由于现在收集器基本都采用分代收集算法,所以 Java 堆中还可以细分为:新生代和老年代。再细致一点的有 Eden 空间、From Survivor 空间、To Survivor 空间等。从内存分配的角度来看,线程共享的 Java 堆中可能划分出多个线程私有的分配缓冲区(Thread Local Allocation Buffer,TLAB)。不过无论如何划分,都与存放内容无关,无论哪个区域,存储的都仍然是对象实例,进一步划分的目的是为了更好地回收内存,或者更快地分配内存。

堆区的调整:通过设置如下参数,可以设定堆区的初始值和最大值,比如 -Xms256M -Xmx 1024M,其中 -X 这个字母代表它是 JVM 运行时参数,ms 是 memory start 的简称,中文意思就是内存初始值,mx 是 memory max 的简称,意思就是最大内存。

在通常情况下,服务器在运行过程中,堆空间不断地扩容与回缩,会形成不必要的系统压力所以在线上生产环境中 JVM 的 Xms 和 Xmx 会设置成同样大小,避免在 GC 后调整堆大小时带来的额外压力。

堆的默认空间分配:查看当前 JDK 版本所有默认的 JVM 参数:=======》java -XX:+PrintFlagsFinal -version

Java 虚拟机栈:

对于每一个线程,JVM 都会在线程被创建的时候,创建一个单独的栈。也就是说虚拟机栈的生命周期和线程是一致,并且是线程私有的。

栈帧(Stack Frame)是用于支持虚拟机进行方法调用和方法执行的数据结构。栈帧存储了方法的局部变量表(局部变量表:定义为一个数字数组,用于方法参数和方法内部的局部变量,包括三种数据类型:8种基本数据类型+引用数据类型地址+returnAddress类型(指向一条字节码指令的地址) )、操作数栈(操作数栈主要用于保存运算过程中的的中间结果,同时作为计算过程中变量的临时的存储空间.)、动态链接(动态链接就是讲指令中的符号引用转化为真实的方法地址(直接引用)和方法返回地址等信息。每一个方法从调用至执行完成的过程,都对应着一个栈帧在虚拟机栈里从入栈到出栈的过程。

本地方法栈:

本地方法栈(Native Method Stack)与虚拟机栈所发挥的作用是非常相似的,它们之间的区别不过是虚拟机栈为虚拟机执行 Java 方法(也就是字节码)服务,而本地方法栈则为虚拟机使用到的 Native 方法服务。在虚拟机规范中对本地方法栈中方法使用的语言、使用方式与数据结构并没有强制规定,因此具体的虚拟机可以自由实现它。甚至有的虚拟机(譬如 Sun HotSpot 虚拟机)直接就把本地方法栈和虚拟机栈合二为一。与虚拟机栈一样,本地方法栈区域也会抛出 StackOverflowError 和 OutOfMemoryError 异常。

拓展:

  • 静态链接:当一个字节码文件被装载进JVM内部时,如果被调用的目标方法在编译器可知,且运行时期不变,这种情况下将调用方法的符号引用转换为直接引用的过程称之为静态链接.对应早期绑定(早期绑定就是指被调用的目标方法如果在编译期可知,且运行时期不变,即可将这个方法与所属的类型进行绑定,这样以来,由于明确了被调用的方法是哪一个,因此可以使用静态链接的方式将符号引用转换为直接引用).
  • 动态链接:如果被调用的方法在编译期无法被确定下来,只能够在程序运行期将调用方法的符号引用转换为直接引用,由于这种引用转换过程具备动态性,因此被称之为动态链接.对应晚期绑定(如果被调用方法在编译期无法被确定下来,只能在程序运行期根据实际的类型绑定相应的方法,这种绑定方式被称为晚期绑定).

程序计数器:

程序计数器(Program Counter Register)是一块较小的内存空间。是线程私有的。它可以看作是当前线程所执行的字节码的行号指示器

直接内存:

直接内存(Direct Memory)并不是虚拟机运行时数据区的一部分,也不是 Java 虚拟机规范中定义的内存区域。但是这部分内存也被频繁地使用,而且也可能导致 OutOfMemoryError 异常出现

Code Cache:

JVM 代码缓存是 JVM 将其字节码存储为本机代码的区域 。我们将可执行本机代码的每个块称为 nmethod。该 nmethod 可能是一个完整的或内联 Java 方法。

2.Java如何标记垃圾

Java中的垃圾回收是通过标记-清除算法实现的。当一个对象不再被任何引用指向时,它就可以被垃圾回收器回收。

在Java中,垃圾回收器通过可达性分析算法来标记垃圾对象。可达性分析算法是从一组被称为“GC Roots”的根对象开始遍历内存中的所有对象,任何能够被遍历到的对象都被认为是“存活”的对象,而未被遍历到的对象则被认为是“垃圾”对象。

Java中的GC Roots包括以下几种类型的对象:

  1. 虚拟机栈中引用的对象
  2. 方法区中静态属性引用的对象
  3. 方法区中常量引用的对象
  4. 本地方法栈中JNI(Java Native Interface)引用的对象

垃圾回收器会从GC Roots开始遍历内存中的所有对象,标记出所有被引用的对象,然后将没有被标记的对象视为垃圾对象进行回收。这个过程中,需要注意的是,垃圾回收器不能回收互相引用的对象,即使这些对象已经没有任何被引用的路径,因为它们之间仍然存在一条循环引用的路径,所以它们仍然被视为“存活”的对象。

需要注意的是,Java虚拟机的垃圾回收机制是自动的,程序员无法直接干预。但是,可以通过一些手段来优化垃圾回收的效率,比如尽量避免创建大量的临时对象,避免使用过多的finalize()方法等。

3.GC回收的是哪里?

因为虚拟机栈、本地方法栈、程序计数器是线程私有的,随着线程的消亡而消亡,方法结束或者线程结束时,内存自然就跟随着回收了。 GC回收的区域是堆和方法区,为什么回收这两个区域那,因为他们是线程共享的,即java程序中所有的线程都可以访问。

4.常见的垃圾回收算法有哪些?

**分代收集算法:**根据内存对象的存活周期不同,将内存划分成几块,java虚拟机一般将内存分成新生代和老生代,在新生代中,有大量对象死去和少量对象存活,所以采用复制算法,只需要付出少量存活对象的复制成本就可以完成收集;老年代中因为对象的存活率极高,没有额外的空间对他进行分配担保,所以采用标记清理或者标记整理算法进行回收;

**标记清除法:**第一步:利用可达性去遍历内存,把存活对象和垃圾对象进行标记;

第二步:在遍历一遍,将所有标记的对象回收掉;

特点:效率不行,标记和清除的效率都不高;标记和清除后会产生大量的不连续的空间分片,可能会导致之后程序运行的时候需分配大对象而找不到连续分片而不得不触发一次GC(垃圾回收);

**标记整理法:**第一步:利用可达性去遍历内存,把存活对象和垃圾对象进行标记;第二步:将所有的存活的对象向一段移动,将端边界以外的对象都回收掉;

特点:适用于存活对象多,垃圾少的情况;需要整理的过程,无空间碎片产生;

**复制算法:**将内存按照容量大小分为大小相等的两块,每次只使用一块,当一块使用完了,就将还存活的对象移到另一块上,然后在把使用过的内存空间移除;特点:不会产生空间碎片;内存使用率极低;

5.哪些情况下会出现FULLGC

  1. 调用 System.gc()

只是建议虚拟机执行 Full GC,但是虚拟机不一定真正去执行。不建议使用这种方式,而是让虚拟机管理内存。

  1. 未指定老年代和新生代大小,堆伸缩时会产生fullgc,所以一定要配置-Xmx、-Xms
  2. 老年代空间不足

老年代空间不足的常见场景比如大对象、大数组直接进入老年代、长期存活的对象进入老年代等。

为了避免以上原因引起的 Full GC,应当尽量不要创建过大的对象以及数组。

除此之外,可以通过 -Xmn 虚拟机参数调大新生代的大小,让对象尽量在新生代被回收掉,不进入老年代。

还可以通过 -XX:MaxTenuringThreshold 调大对象进入老年代的年龄,让对象在新生代多存活一段时间。

在执行Full GC后空间仍然不足,则抛出错误:java.lang.OutOfMemoryError: Java heap space

  1. JDK 1.7 及以前的(永久代)空间满

在 JDK 1.7 及以前,HotSpot 虚拟机中的方法区是用永久代实现的,永久代中存放的为一些 Class 的信息、常量、静态变量等数据。

当系统中要加载的类、反射的类和调用的方法较多时,永久代可能会被占满,在未配置为采用 CMS GC 的情况下也

会执行 Full GC。

如果经过 Full GC 仍然回收不了,那么虚拟机会抛出java.lang.OutOfMemoryError PermGen space

为避免以上原因引起的 Full GC,可采用的方法为增大Perm Gen或转为使用 CMS GC。

  1. 空间分配担保失败

空间担保,下面两种情况是空间担保失败:

1、每次晋升的对象的平均大小 > 老年代剩余空间

2、Minor GC后存活的对象超过了老年代剩余空间

注意GC日志中是否有promotion failed和concurrent mode failure两种状况,当出现这两种状况的时候就有可能会触发Full GC。

promotion failed 是在进行 Minor GC时候,survivor space空间放不下只能晋升老年代,而此时老年代也空间不足时发生的。

concurrent mode failure 是在进行CMS GC过程,此时有对象要放入老年代而空间不足造成的,这种情况下会退化使用Serial Old收集器变成单线程的,此时是相当的慢的。

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

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

相关文章

CRM系统的这些功能助您高效管理客户

客户管理可以理解为企业收集并利用客户信息,满足客户的需求,从而提升客户价值的过程。CRM系统一直被誉为客户管理的“神器”,下面我们就来说说CRM系统有哪些功能可以管理客户? 1、客户信息管理 CRM可以帮助企业收集客户的基本信…

C++11(下)

可变参数模板 C11的新特性可变参数模板能够创建可以接受可变参数的函数模板和类模板. 相比C98/03, 类模版和函数模版中只能含固定数量的模版参数, 可变模版参数无疑是一个巨大的改进, 然而由于可变模版参数比较抽象, 使用起来需要一定的技巧, 所以这块还是比较晦涩的.掌握一些基…

《Spring Cloud Alibaba 从入门到实战》分布式配置

分布式配置 1、简介 Nacos 提供用于存储配置和其他元数据的 key/value 存储,为分布式系统中的外部化配置提供服务器端和客户端支持。 Spring Cloud Alibaba Nacos Config 是 Config Server 和 Client 的替代方案,在特殊的 bootstrap 阶段,…

路灯控制系统中漏电保护怎么实施

应用场景1 应用于路灯配电箱的漏电检测 功能 可实时监测和显示路灯配电箱内多回路的剩余电流; 每只剩余电流监测仪最多可监测16个回路的剩余电流,剩余电流监测范围为1mA-30A; 每路剩余电流监测均可设置报警值,报警值的设置范围…

手机如何制作个人博客?安卓Termux+Hexo搭建博客网站并远程访问

文章目录 前言 1.安装 Hexo2.安装cpolar3.远程访问4.固定公网地址 前言 Hexo 是一个用 Nodejs 编写的快速、简洁且高效的博客框架。Hexo 使用 Markdown 解析文章,在几秒内,即可利用靓丽的主题生成静态网页。 下面介绍在Termux中安装个人hexo博客并结合…

Gateway全局异常处理及请求响应监控

前言 我们在上一篇文章基于压测进行Feign调优完成的服务间调用的性能调优,此时我们也关注到一个问题,如果我们统一从网关调用服务,但是网关因为某些原因报错或者没有找到服务怎么办呢? 如下所示,笔者通过网关调用acc…

dToF直方图之美_激光雷达多目标检测

直方图提供了一种简单有效的方法来分析信号分布并识别与目标存在相对应的峰值,并且能够可视化大量数据,让测距数形结合。在车载激光雷达中,对于多目标检测,多峰算法统计等,有着区别于摄像头以及其他雷达方案的天然优势。 如下图,当中有着清晰可见的三个峰值,我们可以非…

基于ssm的电动车租赁网站论文

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术,让传统数据信息的管理升级为软件存储,归纳,集中处理数据信息的管理方式。本电动车租赁网站就是在这样的大环境下诞生,其可以帮助管理者在短时间内处理完毕庞大的数据信息&…

Draw.io or diagrams.net 使用方法

0 Preface/Foreword 在工作中,经常需要用到框图,流程图,时序图,等等,draw.io可以完成以上工作。 official website:draw.io 1 Usage 1.1 VS code插件 draw.io可以扩展到VS code工具中。

Java Web——过滤器 监听器

目录 1. Filter & 过滤器 1.1. 过滤器概述 1.2. 过滤器的使用 1.3. 过滤器生命周期 1.4. 过滤器链的使用 1.5. 注解方式配置过滤器 2. Listener & 监听器 2.1. 监听器概述 2.2. Java Web的监听器 2.2.1. 常用监听器 2.2.1.1. ServletContextListener监听器 …

SM4加密算法的侧信道攻击实现

SM4 算法有多个位置存在泄漏点,如下图所示: 在位置1和2,可以逐个字节攻击密钥,因为密钥和中间结果之间没有扩散,这时通常取Sbox的输出作为攻击点,因为在位置2处的功耗是大于位置1的,但是在FPGA…

ODOO领先其他ERP的王炸功能:作业路线!(含MTO模式配置图表)

和众多ERP系统比较,ODOO-ERP中的作业路线功能可谓相当强大,可以自行定义供应链路线,以及单据同步生成。极大地增强了不同业务场景的适应性和业务管理效率! 自定义供应路线的特点:对于很多灵活多变的企业而言&#xff…

Java架构师系统架构实现高内聚低耦合

目录 1 导语2 边界内聚耦合概述3 聚焦内聚4 关注耦合5 如何实现高内聚低耦合6 内聚耦合规划不当的效果7 总结想学习架构师构建流程请跳转:Java架构师系统架构设计 1 导语 架构设计的核心维度,从系统的扩展性、高性能、高可用、高安全性和伸缩性五个维度进行了探讨,并介绍了…

JavaEE:计算机是如何工作的

JavaEE学什么? 主要学习Java开发网站后端,为后面学习Spring做铺垫 涉及的内容: 1)操作系统基础知识 2)多线程知识 3)文件操作 4)网络编程 5)网络原理 6)JVM 计算…

用到了C语言的函数指针功能。

请选择一个功能&#xff1a; 1. 加法 2. 减法 3. 乘法 4. 除法 5. 取模 6. 阶乘 7. 判断素数 8. 球体体积 9. 斐波那契数列 10. 幂运算 11. 最大公约数 12. 最小公倍数 13. 交换数字 14. 排序 15. 退出 请选择一个选项&#xff1a; #include <stdio.h> #include <stdl…

強強联手!M88明陞宣布与G2 电子竞技俱乐部成为官方合作伙伴!

M88明陞作为亚洲领先的在线游戏平台&#xff0c;正式宣布与G2电子竞技俱乐部建立具有突破性意义的官方合作伙伴关系&#xff0c;G2电子竞技俱乐部是全球领先的电子竞技品牌之一。作为官方合作伙伴关系&#xff0c;双方将合作开展一系列活动。 M88明陞将在G2 电子竞技俱乐部追求…

工单质检上线提升企业IT服务质量管理,智能服务能力再添新翼!甄知燕千云全新版本V1.26.0发布!

燕千云数智化业务服务平台在11月24日发布了V1.26.0版本&#xff0c;本次主要新增了工单质检、SLA绩效管理和上下游管理能力升级、以及自动预测工单流转趋势的功能&#xff0c;以支持更多的IT服务场景。同时&#xff0c;呼叫中心新增了智能分配客服、工单关联会话记录、客服消息…

RT-Thread学习笔记(六):RT_Thread系统死机日志定位

RT_Thread系统死机日志定位 一、RT_Thread系统死机日志定位二、Cortex-M3 / M4架构知识2.1 Cortex-M3 / M4架构概述2.2 寄存器用途 三、排查步骤 一、RT_Thread系统死机日志定位 RT-Thread 系统发生hardfault死机时&#xff0c;系统默认会打印出一系列寄存器状态帮助用户定位死…

NOIP2016提高组第二轮day2 - T3:愤怒的小鸟

题目链接 [NOIP2016 提高组] 愤怒的小鸟 题目描述 Kiana 最近沉迷于一款神奇的游戏无法自拔。简单来说&#xff0c;这款游戏是在一个平面上进行的。 有一架弹弓位于 ( 0 , 0 ) (0,0) (0,0) 处&#xff0c;每次 Kiana 可以用它向第一象限发射一只红色的小鸟&#xff0c;小鸟…

【T3】安装畅捷通T3软件,错误代码0x800A0146,描述:未找到标识符为‘138’的资源。

【问题描述】 安装畅捷通T3软件过程中&#xff0c;提示&#xff1a; 错误代码0x800A0146 描述&#xff1a;未找到标识符为‘138’的资源&#xff0c; 安装程序将立即终止。 【解决方法】 该错误是因为安装过程中检测到数据库版本过高。 首先T3普及版/标准版11.2版本支持数据库…