当前位置: 首页 > news >正文

JVM面试题

JVM面试题

什么是程序计数器?

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

介绍一下Java堆

堆内存是线程共享的区域:主要用来保存对象实例、数组等,内存不够则抛出OutOfMemoryError异常

组成:年轻代+老年代组成

  • 年轻代被分为三个部分:伊甸园区和两个大小Survivor区
  • 老年代主要用来保存生命周期长的对象,一般是老的对象

Jdk1.7和1.8的区别

  • 1.7中有一个永久代,存储的是类信息、静态变量、常量、编译后的代码
  • 1.8移除了永久代,吧数据存储到了本地内存的元空间中,防止内存溢出
栈内存
什么是虚拟机栈
  • 每个线程运行时所需要的内存称为虚拟机栈
  • 每个栈由多个栈帧组成,对应着每次方法调用时所占用的内存
  • 每个线程只有一个活动栈帧,对应着当前正在执行的那个方法
垃圾回收是否涉及栈内存

垃圾回收主要指的是堆内存,当栈帧弹出后,内存自动释放

栈内存越大越好吗

未必,默认的栈内存为1024k,栈帧过大导致线程数变少

方法内的局部变量是否线程安全?
  • 如果方法内局部变量没有逃离方法的作用范围,它是线程安全的
  • 如果局部变量引用了对象,并逃离方法的作用范围需要考虑线程安全问题
什么情况下会导致栈内存溢出?
  • 栈帧过多 例如:递归调用
  • 栈帧过大导致内存溢出
堆栈的区别是什么?
  • 栈内存一般用来存储局部变量和方法调用,堆内存用来存储Java对象和数组。碓需要GC垃圾回收,栈不需要
  • 栈内存是线程私有的,堆内存是共有的
  • 异常错误不同:
    • 栈内存不足:java.lang.StackOverFlowError
    • 堆内存不足:java.lang.OutOfMemoryError
方法区
解释一下方法区
  • 方法区是各个线程共享的内存区域
  • 主要用来存储类的信息、运行时常量池
  • 虚拟机启动的时候创建,关闭的时候释放
  • 方法区的内存无法满足分配请求则会抛出OutOfMemeoryError:Metaspace
介绍一下运行时常量池

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

当类被加载,它的常量池信息就会放入运行时常量池,并把里面的符号地址变为真实地址

类加载器
什么是类加载器,类加载器有哪些?

JVM只会运行二进制文件,类加载器的作用就是将字节码文件加载到JVM中,从而让java程序能够启动起来

在这里插入图片描述

  • 类加载器包括四种
    • 启动类加载器 加载核心类库
    • 扩展类加载器 加载/jre/lib/ext下的拓展类文件
    • 应用类加载器 加载classpath下的字节码文件
    • 自定义加载器
什么是双亲委派机制?

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

为什么要使用双亲委派机制?
  • 通过双亲委派机制可以避免一个类被重复加载,当父类已经加载后则无需重复加载,保证唯一性
  • 为了安全,保证类库API不会被修改
*类加载器的执行流程

类加载器的执行流程共分为7个阶段

  • 加载:查找和导入class文件
  • 验证:保障加载类的正确性
  • 准备:为类变量分配内存并设置类变量的初始化值 (static修饰的变量)
  • 解析:把类中的符号引用转为直接引用
  • 初始化:对类的静态变量、静态代码块执行初始化操作
  • 使用:JVM开始从入口方法执行用户的程序代码
  • 卸载:当用户程序代码执行完毕后,JVM开始销毁创建的Class对象

在这里插入图片描述

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

如果一个或多个对象没有任何的引用指向它了,那么这个对象就是垃圾,如果定位了垃圾则可能被垃圾回收器回收

定位垃圾的方法
  • 引用计数法 有循环引用问题
  • 可达性分析算法
    • 扫描堆中的对象,看是否能够沿着GC root对象为起点的引用链找到该对象,找不到则可以回收
哪些对象可以作用GC root?
  • 虚拟机栈中引用的对象
  • 方法区中类静态属性引用的对象
  • 方法区中常量引用的对象
  • 本地方法栈JNI(Native方法)引用的对象
JVM垃圾回收算法有哪些?
标记清除算法

垃圾回收分为两个阶段,分别是标记和清除,效率高,有磁盘碎片,内存不连接

标记整理算法

和标记清除一样,将存活的对象都向内存的另一端移动,然后清理边界以外的垃圾,无碎片,对象需要移动,效率低,一般老年代使用

复制算法

将原有的内存空间一分为二,每次只用其中一块,正在使用的对象复制到另一个内存空间中,然后该内存清空,交换两个内存的角色,完成垃圾回收:无碎片,内存使用效率低

说一下JVM中的分代回收
堆的区域划分
  • 堆被分为了两份:新生代和老年代 1:2
  • 新生代又被分为三个区域,Eden区,幸存者区(from和to)8:1:1
对象分代回收策略
  • 新对象的创建都会被分到eden区

  • 伊甸园区内存不足时,标记伊甸园区和from区中的存活对象

  • 将存活对象复制到to中,复制完成后伊甸园区和from区的内存都会得到释放

  • 经过一段时间后伊甸园区的内存又出现不足,标记eden区域to区域存活的对象,将其复制到from区

  • 当幸存区的对象熬过几次回收(最多15次),晋升到老年代(幸存者区不足或者大对象都会提前晋升)

MinorGC、Mixed GC、FullGC的区别是什么?
  • MinorGC(yiung GC)发生在新生代的垃圾回收,暂停时间短(STW)
  • Mixed GC 新生代+老年代部分区域的垃圾回收,G1独有
  • Full GC 新生代+老年代完整垃圾回收,暂停时间长(STW),应尽力避免
三色标记法是什么?

在CMS垃圾回收器中采用三种颜色表示对象被扫描的状态

  • 白色:表示对象尚未被垃圾回收器访问过(分析结束阶段表示不可达)
  • 灰色:表示对象已经被垃圾回收器访问过,但对象至少存在一个引用没有被扫描
  • 灰色表示对象以及引用都被扫描过了
三阶段

初始标记阶段:将GC Roots直接关联的对象进行标记为灰色

并发标记阶段:扫描整个引用链,没有字节点直接将当前节点标为黑色,有字节点的将当前节点变为黑色,子节点变为灰色

重复并发标记阶段:确认灰色节点没有子节点后将节点标记为黑色,然后进行清除

JVM有哪些垃圾回收器?
  • 串行垃圾回收器:Serial GC、SerialOld GC
  • 并行垃圾回收器:Parallel Old GC、ParNew GC 默认
  • CMS(并发)垃圾回收器
  • G1:作用在新生代和老年代
聊一下G1垃圾回收器
  • 应用于新生代和老年代,在JDK9之后默认使用G1
  • 将内存划分为多个大小相等的区域,每个区域都可以充当eden、survivor、old、humongous,其中humongous专门为大对象准备
  • 采用复制算法
  • 响应时间和吞吐量兼顾
  • 分为三个阶段:新生代回收(stw)、并发标记(重复标记stw)、混合收集
  • 如果并发失败(回收速度赶不上对象创建速度)会触发FullGC

在这里插入图片描述

在这里插入图片描述

<在这里插入图片描述

在这里插入图片描述

在这里插入图片描述


http://www.mrgr.cn/news/54727.html

相关文章:

  • OpenAI GPT-o1实现方案记录与梳理
  • Java集合常见知识总结(中)
  • 【STM32项目_2_基于STM32的宠物喂食系统】
  • 什么是HarmonyOS元服务?
  • Java全栈经典面试题剖析2】JavaSE面向对象1
  • AI绘图神器Napkins——文字转图表
  • Linux笔记之文件查找和搜索命令which,find,locate,whereis总结
  • 基于x86_64汇编语言简单教程6: 变量,常量,与运算
  • Axure中继器时间筛选
  • 将 centos7 的根分区由非逻辑卷转换成使用逻辑卷
  • halcon的intensity算子到底是Mean灰度均值最大表示清晰度最高,还是Deviation灰度偏差最大表示清晰度最高?
  • 深入了解 Flannel(2):vxlan模式下的跨主机pod通信
  • Vue框架基础知识
  • 电能表预付费系统-标准传输规范(STS)(14)
  • 【数据结构】【单调栈】视野总和
  • 动态规划之打家劫舍
  • Python 类
  • 【计网】从零开始理解TCP协议 --- 拥塞控制机制,延迟应答机制,捎带应答,面向字节流
  • 【OD】【E卷】【真题】【100分】最大利润贪心的商人(PythonJavaJavaScriptC++C)
  • Docker无法拉取镜像解决办法
  • 程序员数学:用Python学透线性代数和微积分 中文目录
  • #P3014. 数字游戏
  • STM32F1+HAL库+FreeTOTS学习18——任务通知
  • Comfyui如何快速选出图像的高光和阴影 _ layerstyle节点
  • 动态规划58道算法题
  • 【Modern C++】特性学习与补漏