JVM常见面试题

一、JVM的内存区

JVM的内存区分为虚拟机栈、本地方法栈、程序计数器、堆、方法区。

其中,虚拟机栈、本地方法栈、程序计数器是每个线程独占区,堆、方法区是所有线程共享的内存区域。

虚拟机栈:每个线程在运行时都会创建一个虚拟机栈。栈中存储的是栈帧(Stack Frame),每个方法调用都会创建一个栈帧,并将其压入栈中。

特点:

  • 每个线程都有自己独立的虚拟机栈。
  • 栈帧包含局部变量表、操作数栈、动态链接、方法出口等信息。
  • 生命周期与线程相同。

**本地方法栈:**为执行本地native方法(如C/C++代码)提供支持。

特点:

  • 类似于虚拟机栈,但专门用于本地方法调用。
  • 每个线程有自己的本地方法栈。

程序计数器:记录当前线程所执行的字节码指令地址。如果线程正在执行的是一个Java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址;如果正在执行的是Native方法,这个计数器值为空(Undefined)。

特点:

  • 每个线程都有自己的程序计数器。
  • 保证线程切换后能恢复到正确的执行位置

**堆:**所有对象实例以及数组都要在堆上分配

特点:

  • 垃圾回收的主要区域。
  • 可细分为年轻代(Young Generation)和老年代(Old Generation)。

方法区: 存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码缓存等数据。

特点:

  • 在HotSpot虚拟机中,方法区的实现称为"永久代"(PermGen,在JDK 8之前)或"元空间"(Metaspace,在JDK 8及之后)。

**运⾏时常量池:**运行时常量池是方法区的一部分。JDK 8之前位于永久代(堆内存)中,在JDK 8及之后位于元空间(本地内存)中。

二、垃圾回收算法

1、垃圾回收的基本概念

(1)**对象可达性分析:**JVM通过一系列称为"根节点(Roots)"的对象开始,遍历所有引用链,找到所有可达的对象。所有不可达的对象被认为是垃圾,可以被回收。

(2)根节点(Roots):

  • 虚拟机栈中引⽤的对象(本地变量表)
  • 本地方法栈中引⽤的对象
  • 方法区中静态属性引⽤的对象
  • 方法区中常量引⽤的对象

2、主要的垃圾回收算法

(1)标记-清除算法:

  • 标记阶段:从根节点开始遍历所有对象,并标记所有不可达的对象。
  • 清除阶段:扫描整个堆,回收被标记的对象(即垃圾对象)。

缺点:

  • 容易产生内存碎片,导致后续分配大对象时可能失败。
  • 标记和清除过程需要遍历整个堆,效率较低。

(2)标记-整理算法

类似于标记-清除,但在清除阶段,会将存活的对象移动到堆的一端,然后清理剩余部分。

缺点:

  • 移动对象的过程较为复杂,耗时较长。

(3)复制算法

将堆分成两个区域,每次只使用一个区域,当一个区域满了,将存活的对象复制到另一个区域,并清理当前区域。

缺点:

  • 需要额外的空间来存储对象的副本。
  • 适用于年轻代(Young Generation),因为大多数对象生命周期较短。

(4)分代回收算法

基于大多数对象生命周期较短的观察,JVM将内存划分为新生代和老年代。分配的依据是对象的经历的GC次数。对象创建时,一般在新生代的Eden Space申请内存,当经历一次GC之后对象还存活,那么对象的年龄+1,当对象年龄超过一定值(默认值为 15),对象就会进入老年代,当然有足够大的对象,即使年龄未达到阈值,这些对象也可能被直接晋升到老年代,因为复制一个大对象耗时。

三、新生代和老年代的区别

对象特性:大多数新创建的对象会被分配到新生代,这些对象的生命周期通常较短,很多对象在创建后不久就不再使用,成为垃圾对象等待回收。而老年代存储的是经过多次垃圾回收仍然存活的对象。

垃圾回收算法的区别:新生代主要使用复制算法 进行垃圾回收。新生代内存被分为一个大的Eden区和两个小的Survivor区。新对象优先分配在Eden区,当Eden区满时,触发Minor GC (新生代垃圾回收),将Eden区和一个Survivor区中存活的对象复制到另一个Survivor区,然后清空Eden区和之前使用过Survivor区。经过多次Minor GC后仍存活的对象被晋升到老年代。老年代一般采用标记-清除算法 或者标记-整理算法。 老年代的垃圾回收成为Major GCFull GC

四、主要的垃圾回收机制

**Serial收集器:**新生代,单线程,简单高效,适合单核处理器和小内存环境

**ParNew收集器:**新生代,并行执行,减少停顿时间,适合多核处理器

**Parallel Scavenge收集器:**新生代,高吞吐量,减少垃圾回收时间,适合后台处理

**CMS收集器:**老年代,并发执行,减少停顿时间,适合对响应时间要求高的应用

**G1收集器:**新生代+老年代,分区管理,优先回收垃圾最多的区域,适合大堆内存和低延迟需求

相关推荐
半聋半瞎4 小时前
【进程和线程】(面试高频考点)
java·jvm·面试
一桶8 小时前
金融级JVM深度调优实战的经验和技巧
jvm
狂奔小菜鸡8 小时前
Java运行时数据区
java·jvm·后端
白晨并不是很能熬夜10 小时前
【JVM】字节码指令集
java·开发语言·汇编·jvm·数据结构·后端·javac
钢板兽12 小时前
Java后端高频面经——JVM、Linux、Git、Docker
java·linux·jvm·git·后端·docker·面试
Anarkh_Lee16 小时前
图解JVM - 13.垃圾回收器
java·jvm·后端
吃海鲜的骆驼18 小时前
JVM_八股&场景题
jvm
阿坨1 天前
JVM G1垃圾回收器详细解析
jvm
JouJz1 天前
Java虚拟机之垃圾收集(一)
java·开发语言·jvm