java面试(JVM)

news2024/11/18 17:49:37

JVM是什么

Java Virtual Machine Java程序的运行环境(java二进制字节码的运行环境)
好处:

  1. 一次编写,到处运行
  2. 自动内存管理,垃圾回收机制

JVM由哪些部分组成,运行流程是什么

在这里插入图片描述

什么是程序计数器

程序计数器:线程私有的,内部保存字节码的行号。用于记录正在执行的字节码指令的地址。

Java堆

线程共享的区域:主要用来保存对象实例,数组等,当堆中没有内存空间可分配给实例,也无法再扩展时,则抛出OutOfMemoryError异常
在这里插入图片描述
年轻代被划分为三部分,Eden区和两个大小严格相同的Survivor区,根据JVM的策略,在经过几次垃圾收集后,任然存活于Survivor的对象将被移动到老年代区间。
老年代主要保存声明周期长的对象,一般是一些老的对象
元空间保存类信息,静态变量,常量,编译后的代码
在这里插入图片描述

虚拟机栈

Java Virtual Machine Stacks(java虚拟机栈)

  1. 每个线程在运行时所需要的内存,称为虚拟机栈,先进后出
  2. 每个栈由多个栈帧组成(frame)组成,对应着每次方法调用时所占用的内存
  3. 每个线程中只能有一个活动栈帧,对应着当前正在执行的那个方法

垃圾回收是否涉及栈内存

垃圾回收主要指就是堆内存,当栈帧弹栈以后,内存就会释放

栈内存分配的越大越好吗

未必,默认的栈内存通常为1024K
栈帧过大会导致线程数变少,例如,机器总内存为512m,目前能活动的线程数则为512个,如果把栈内存改为2048K,那么能活动的栈帧就会减半

方法内的局部变量是否线程安全

  1. 如果方法内局部变量没有逃离方法的作用范围,他是线程安全的
  2. 如果是局部变量引用的对象,并逃离方法的作用范围,需要考虑线程安全

栈内存溢出情况

  1. 栈帧过多导致栈内存溢出,典型问题:递归调用
  2. 栈帧过大导致栈内存溢出

堆栈的区别是什么

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

方法区

  1. 方法区(Method Area)是各个线程共享的内存区域
  2. 主要存储类的信息,运行时常量池
  3. 虚拟机启动的时候创建,关闭虚拟机时释放
  4. 如果方法区域中的内存无法满足分配请求,则会抛出OutOfMemoryError:Metaspace

常量池

可以看做是一张表,虚拟机指令根据这张常量表找到要执行的类名,方法名,参数类型,字面量等信息

运行时常量池

常量池是*.class文件中的,当该类被加载,他的常量池信息就会放入运行时常量池,并把里面的符号地址变为真实地址

直接内存

直接内存:并不属于JVM的内存结构,不由JVM进行管理。是虚拟机的系统内存,常见于NIO操作时,用于数据缓冲区,他分配回收成本较高,但读写性能高
在这里插入图片描述

类加载器

JVM只会运行二进制文件,类加载器的作用就是将字节码文件加载到JVM中,从而让Java程序能够启动起来
在这里插入图片描述

双亲委派模型

加载某一个类,先委托上一级的加载器进行加载,如果上级加载器也有上级,则会继续向上委托,如果该类委托上级没有被加载,子加载器尝试加载该类

为什么采用双亲委派机制

  1. 通过双亲委派机制可以避免某一个类被重复加载,当父类已经加载后则无需重复加载,保证唯一性
  2. 为了安全,保证类库API不会被修改

类装载的执行流程

类从加载到虚拟机中开始。直到卸载为止,他的整个生命周期包括了:加载,验证,准备。解析。初始化,使用和卸载这7个阶段。其中,验证,准备,和解析这三个部分统称为连接(linking)
在这里插入图片描述

加载

  1. 通过类的全名,获取类的二进制数据流
  2. 解析类的二进制数据流为方法区内的数据结构(Java类模型)
  3. 创建java.lang.Class类的实例,表示该类型,作为方法区这个类的各种数据的访问入口

验证

验证类是否符合JVM规范,安全性检查

  1. 文件格式验证
  2. 元数据验证
  3. 字节码验证
  4. 符号引用验证:Class文件在其常量池会通过字符串记录自己将要使用的其他类或者方法,检查他们是否存在

准备

为类变量分配内存并设置初始值

  1. static变量,分配空间在准备阶段完成(设置默认值),赋值在初始化阶段完成
  2. static变量是final的基本类型,以及字符串常量,值已确定,赋值在准备阶段完成
  3. static变量是final的引用类型,那么赋值也会在初始化阶段完成

解析

把类中的符号引用转换为直接引用
如:方法中调用了其他方法,方法名可以理解为符号引用,而直接引用就是使用指针直接指向方法

初始化

对类的静态变量和静态代码块执行初始化操作

  1. 如果初始化一个类的时候,其父类尚未初始化,则有限初始化其父类
  2. 如果同时包含多个静态变量和静态代码块,则按照自上而下的顺序依次执行

使用

JVM开始从入口方法开始执行用户的程序代码

  1. 调用静态类成员信息(比如:静态字段,静态方法)
  2. 使用new关键字为其创建对象实例

对象什么时候可以被垃圾回收

如果一个对象或者多个对象没有任何的引用指向他了,那么这个对象现在就是垃圾,如果定位了垃圾,则有可能会被垃圾回收器回收
如果要定位什么是垃圾,有两种方式来确定,第一个是引用计数法,第二个是可达性分析算法

引用计数法

一个对象被引用了一次,在当前对象头上递增一次引用次数,如果这个对象的引用次数为0,代表这个对象可回收
但是当对象之间出现了循环引用的话,引用计数法就会失效

可达性分析算法

现在的虚拟机采用的都是通过可达性分析算法来确定哪些内容是垃圾:
扫描堆中的对象,看看是否能够沿着GC Root对象为起点的引用链找到该对象,找不到表示可以回收

哪些对象可以作为GC root

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

垃圾回收算法有哪些

标记清除算法

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

  1. 根据可达性分析算法得出的垃圾进行标记
  2. 对这些标记为可回收的内容进行垃圾回收
    优点:标记和清除速度较快
    缺点:碎片化较为严重,内存不连贯

标记整理算法

优缺点同标记清除算法,解决了标记清除算法的碎片化的问题。同时,标记压缩算法多了一步,对象移动内存位置的步骤,其效率也有一定影响

复制算法

优点:在垃圾对象多的情况下,效率高,清理后内存无碎片
缺点:分配的2块内存空间,在同一时刻,只能使用一半,内存使用率低

JVM中的分代回收

分代收集算法

在java8时,堆被分为了两份:新生代和老年代【1:2】
在这里插入图片描述
对于新生代,内部又被分为了三个区域

  1. 伊甸园区Ede,新生的对象都分配到这里
  2. 幸存者区survivor(分成from和to)
  3. Eden区,from区,to区【8:1:1】

分代收集算法-工作机制

在这里插入图片描述

  1. 新创建的对象,都会先分配到eden区
  2. 当伊甸园内存不足,标记伊甸园与from(现阶段没有)的存活对象
  3. 将存活对象采用复制算法复制到to中,复制完毕后,伊甸园区和from内部都得到释放
  4. 经过一段时间后伊甸园的内存又出现不足,标记eden区域to区域存货的对象,将存活的对象复制到from区
  5. 当幸存区对象熬过几次回收(最多15次),晋升老年代(幸存区内存不足或大对象会导致提前晋升)

MinorGC,MixedGC,FullGC的区别是什么

  1. MinorGC【young GC】发生在新生代的垃圾回收,暂停时间短【STW】
  2. MixedGC 新生代+老年代部分区域的垃圾回收,G1收集器持有
  3. FullGC:新生代+老年代完整垃圾回收,暂停时间长STW,应尽力避免
    STW(Stop-The-World):暂停所有应用程序线程,等待垃圾回收的线程

JVM有哪些垃圾回收器

在jvm中,实现了多种垃圾回收器,包括

  1. 串行垃圾收集器
  2. 并行垃圾收集器
  3. CMS(并发)垃圾收集器
  4. G1垃圾收集器

串行垃圾回收器

Serial和Serial Old串行垃圾回收器,是指使用单线程进行垃圾回收,堆内存较小,适合个人电脑

  1. Serial作用于新生代,采用复制算法
  2. Serial Old作用于老年代,采用标记-整理算法
    垃圾回收时,只有一个线程在工作,并且java应用中的所有线程都要暂停(STW),等待垃圾回收的完成
    在这里插入图片描述

并行垃圾回收器

Parallel New和Parallel Old是一个并行垃圾回收器,JDK8默认使用此垃圾回收器

  1. Parallel New作用于新生代,采用复制算法
  2. Parallel Old作用于老年代,采用标记-整理算法
    垃圾回收时,多个线程在工作,并且采用java应用中的所有线程都要暂停(STW),等待垃圾回收的完成
    在这里插入图片描述

CMS(并发)垃圾回收器

CMS全称Concurrent Mark Sweep,是一款并发的,使用标记-清除算法的垃圾回收器,该回收器是针对老年代垃圾回收的,是一款以获取最短回收停顿时间为目标的收集器,停顿时间短,用户体验较好。其最大特点是在进行垃圾回收时,应用仍然能正常运行
在这里插入图片描述

G1垃圾回收器

  1. 应用于新生代和老年代,在JDK9之后默认使用G1
  2. 划分成多个区域,每个区域都可以充当eden,survivor,old,humongous,其中humongous专为大对象准备
  3. 采用复制算法
  4. 响应时间与吞吐量兼顾
  5. 分成三个阶段:新生代回收,并发标记,混合收集
  6. 如果并发失败(即回收速度赶不上创建新对象速度),会触发Full GC

Young Collection(年轻代垃圾回收)

  1. 初始时,所有区域都处于空闲状态
  2. 创建了一些对象,挑出一些空闲区域作为伊甸园区存储这些对象
  3. 当伊甸园区需要垃圾回收时,挑出一个空闲区域作为幸存区,用复制算法复制存活对象,需要暂停用户线程
  4. 随着时间流逝,伊甸园区的内存又有不足
  5. 将伊甸园区以及之前幸存区中的存活对象,采用复制算法,复制到信的幸存区,其中较老对象晋升至老年代

Young Collection + Concurrent Mark(年轻代垃圾回收 + 并发标记)

  1. 当老年代占用内存超过阈值(默认是45%)后,触发并发标记,这时无需暂停用户线程
  2. 并发标记完成之后,会有重新标记阶段解决漏标问题,这是需要暂停用户线程
  3. 这些都完成后就知道了老年代有哪些存货对象,随后进入混合收集阶段,此时不会对所哟老年代区域进行回收,而是根据暂停目标优先回收价值高(存货对象少)的区域(这也是Garbage First名称的由来)

Mixed Collection(混合垃圾回收)

混合收集阶段中,参与复制的有eden,survivor,old,复制完成,内存得到释放。进入下一轮的新生代回收,并发标记,混合收集

强引用,软引用,弱引用,虚引用的区别

  1. 强引用:只有所有GC Roots对象都不通过【强引用】引用该对象,该对象才能被垃圾回收
  2. 软引用:仅有软引用引用该对象时,在垃圾回收后,内存仍不足时会再次触发垃圾回收
  3. 弱引用:仅有弱引用引用该对象时,在垃圾回收时,无论内存是否充足,都会回收弱引用对象
  4. 虚引用:必须配合引用队列使用,被引用对象回收时,会将虚引用入队,由Reference Handler线程调用虚引用相关方法释放直接内存

JVM调优的参数可以在哪里设置参数值

  1. war包部署在tomcat中设置:修改TOMCAT_HOME/bin/catalina.sh文件
  2. jar包部署在启动参数设置:通常在linux系统下直接加参数启动springboot项目

调优的参数都有哪些

对于JVM调优,主要就是调整年轻代,老年代,元空间的内存空间大小以及使用的垃圾回收器类型

  1. 设置堆空间的大小:设置堆的初始大小和最大大小,为了防止垃圾收集器在初始大小,最大大小之间收缩堆而产生额外的空间,通常把最大,初始大小设置为相同的值(堆空间设置多少合适)
    1. 最大大小默认是物理内存的1/4,初始大小是物理内存的1/64
    2. 堆太小,可能会频繁的导致年轻代和老年代的垃圾回收,会产生stw,暂停用户线程
    3. 堆内存大肯定是好的,存在风险,假如发生了fullgc,他会扫描整个内存空间,暂停用户线程的时间长
    4. 设置参考推荐:尽量大,也要考察一下当前计算机其他程序的内存使用情况
-Xms:设置堆的初始化大小
-Xmx:设置堆的最大大小
不指定单位默认为字节,指定单位按照指定的单位设置	
  1. 虚拟机栈的设置:每个线程默认会开启1M的内存,用于存放栈帧,调用参数,局部变量等,但一般256K就够用。通常减少每个线程的堆栈,可以产生更多的线程,但这实际上还受限于操作系统
-Xss 对每个线程stack大小的调整,-Xss128k
  1. 年轻代中Eden区和两个Survivor区的大小比例:设置年轻代中Eden区和两个Survivor区的大小比例。该值如果不设置,则默认比例为8:1:1。通过增大Eden区的大小,来减少YGC发生的次数。但有时候我们发现,虽然次数减少了,但Eden区满的时候,由于占用的空间较大,导致释放缓慢,因此需要按照程序情况去调优
-XXSurvivorRatio=8 ,表示年轻代中的分配比率:survivor:eden=2:8
  1. 年轻代晋升老年代阈值
-XX:MaxTenuringThreshold=threshold
默认为15
取值范围0-15
  1. 设置垃圾回收收集器:通过增大吞吐量来提高系统性能,可以通过设置并行垃圾回收器
-XX:+UseParallelGC
-XX:+UseParallelOldGC

-XX:+UseG1GC

JVM调优工具

  1. 命令工具
    1. jps:进程状态信息
    2. jstack:查看java进程内线程的堆栈信息
    3. jmap:查看堆转信息
    4. jhat:堆转储快照分析工具
    5. jstat:JVM统计监测工具
  2. 可视化工具
    1. jconsole:用于对jvm的内存,线程,类的监控
    2. VisualVM:能够监控线程,内存情况

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

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

相关文章

ABB机器人---基础编程

目录 第一章 代码解释 1.1 基础代码 1.1.2 关于 VAR robtarget pos 1.1.3 关于四元数 1.2 机器人初始化程序 1.3 配置通信 (ProfiNet 示例,ABB RAPID) 1.4 设置干涉区 (ABB RAPID) 1.5 示教轨迹和自动过程 (ABB RAPID) 1.6 配置抓手并进行抓取操作 (ABB RA…

Linux: network: TCP: zero window size/window full 示例

最近遇到一个问题,当前机器的CPU使用率非常高,然后导致其中一个程序处理socket的数据过慢,然后出现下面的zero的示例。 下面是在接收buff用光的时候,发出的 TCP zeroWindows的消息 这种问题就是内存,CPU,网速之间的性能取舍。具体解决的话,需要看具体的需要是什么样的?…

他用AI,抄袭了我的AI作品

《大话西游》里面有一句经典台词:每个人都有一个妈,但是“你妈就一定是你妈吗?” 用AI创作的艺术作品,也走进类似的困境:如何证明你用AI生成的作品,就是你的作品? 近日,腾讯科技独…

三星固态硬盘870evo与qvo的区别

三星固态硬盘870evo与qvo的区别 三星固态硬盘870 EVO和QVO的区别主要有以下几点: 1闪存颗粒不同:三星固态QVO采用的是QLLC闪存颗粒,而三星固态870 EVO则是TLC闪存颗粒。 2传输速度不同:三星固态QVO传输速度比较低,而三…

电路仿真软件:点亮教学新篇章,十大便利助力高效学习

在信息化时代的浪潮中,电路仿真软件以其独特的优势,逐渐在教学领域崭露头角。它不仅能够帮助学生更好地理解电路知识,还能提升教师的教学效果。接下来,让我们一起探讨电路仿真软件对教学带来的十大便利。 一、直观展示电路原理 电…

Unity | 框架MVC

目录 一、MVC介绍 二、搭建UI界面 三、代码实现 1.Model层 2.View层 3.Controller层 四、MVC框架测试 五、知识补充 一、MVC介绍 model:数据层。界面展示的数据(需要进行初始化、更新、保存、事件通知等操作),单例模式&am…

【全开源】沃德商协会管理系统源码(FastAdmin+ThinkPHP+Uniapp)

一款基于FastAdminThinkPHPUniapp开发的商协会系统,新一代数字化商协会运营管理系统,以“智慧化会员体系、智敏化内容运营、智能化活动构建”三大板块为基点,实施功能全场景覆盖,一站式解决商协会需求壁垒,有效快速建立…

公司废弃的2014年群晖 DS215J 被我打包回家了,试玩一下

文章目录 简介安装查看存储、cpu、内存等信息DMS 学习video station 简介 群晖DS215J https://www.datastoreworks.com/DS215j.asp 下载:chrome-extension://oemmndcbldboiebfnladdacbdfmadadm/https://global.download.synology.com/download/Document/Hardware/…

ATmega328P加硬件看门狗MAX824L看门狗

void Reversewdt(){ //硬件喂狗,11PIN接MAX824L芯片WDIif (digitalRead(11) HIGH) {digitalWrite(11, LOW); //低电平} else {digitalWrite(11, HIGH); //高电平 }loop增加喂狗调用 void loop() { …… Reversewdt();//喂狗 }

Superset,基于浏览器的开源BI工具

BI工具是数据分析的得力武器,目前市场上有很多BI软件,众所周知的有Tableau、PowerBI、Qlikview、帆软等,其中大部分是收费软件或者部分功能收费。这些工具一通百通,用好一个就够了,重要的是分析思维。 我一直用的Tabl…

vue3中element-plus下拉菜单与图标的使用

更多ruoyi-nbcio功能请看演示系统 gitee源代码地址 前后端代码: https://gitee.com/nbacheng/ruoyi-nbcio 演示地址:RuoYi-Nbcio后台管理系统 http://218.75.87.38:9666/ 更多nbcio-boot功能请看演示系统 gitee源代码地址 后端代码: h…

FANUC机器人点位IO监控指令TC_ONLINE

一、系统变量中打开该指令 在示教器系统变量页面中找到其中的MIX_LOGIC变量,点击enter进入变量设置页面 找到其中的USE_TCOL变量将其中的值改为true 即可在IO显示页面中找到TC_ONLINE的监控选项 在显示页面中也可找到其中的监控条件 二、在点位指令中添加点逻辑指令…

如何从http免费升级到https

使用https协议开头是为了在用户访问网站时提供更安全的网络环境。相比http,使用https有数据加密、身份验证、保护隐私、搜索引擎优化等优势。一般获取https证书,则需要支付费用给证书颁发机构(CA)。还有一些免费的证书证书颁发机构…

【NLP】人机对话

概念 机器翻译就是用计算机把一种语言翻译成另外一种语言的技术 机器翻译的产生与发展 17 世纪,笛卡尔与莱布尼茨试图用统一的数字代码来编写词典 1930 机器脑 1933 苏联发明家特洛阳斯基用机械方法将一种语言翻译为另一种语言 1946 ENIAC 诞生 1949 机器翻译问题…

SpringBoot和Apache Doris实现实时广告推荐系统

本专题旨在向读者深度解读Apache Doris技术,探讨其与SpringBoot框架结合在各类实际应用场景中的角色与作用。本专题包括十篇文章,每篇文章都概述了一个特定应用领域,如大数据分析、实时报告系统、电商数据分析等,并通过对需求的解析、解决方案的设计、实际应用示例的展示以…

CAN笔记第二篇,车载测试继续学起来!

在CAN协议中,“帧”是一个包含完整信息的独立单元,它具有特定的格式和结构,以确保数据在CAN总线上的可靠传输。这里的“帧”字可以理解为: 完整性:一个帧包含了所有必要的信息,从起始到结束,都遵…

3D 生成重建012-Magic123早期使用不同SDS相减的探索

3D 生成重建012-Magic123早期使用不同SDS相减的探索 文章目录 0论文工作1论文方法2效果 0论文工作 Magic123提出了一种两阶段粗到细的方法,用于使用2D和3D先验从野外未曝光图像生成高质量的纹理3D网格。在第一阶段,优化一个神经辐射场,以产…

DQL(数据查询)

目录 1. DQL概念 2. DQL - 编写顺序 3. 基础查询 3.1 查询多个字段 3.2 字段设置别名 3.3 去除重复记录 3.4 案例 4. 条件查询 4.1 语法 4.2 条件 4.3 案例: 5. 聚合函数 5.1 常见的聚合函数: 5.2 语法 5.3 案例: 6. 分组查…

微信小程序抓取数据包(Proxifier联动burpsuite)

1、打开bp,确保开启127.0.0.1:8080监听地址。 2、点击setting--proxy,点击impor CA certificate,生成bp的证书。 保存到桌面为1.cer,文件后缀为cer就OK了,前缀任意 3、安装证书,双击打开刚刚生成…