jvm面试题

1.Jvm基本结构

Jvm由9部分构成:

类加载子系统、堆、栈、方法区、本地方法栈、PC寄存器、直接内存、垃圾回收器、执行引擎。

2.堆、栈、方法区的作用分别是什么?

方法区:就是存放类信息、常量信息、常量池信息、包括字符串字面量和数字常量等。

:在java虚拟机启动的时候建立java堆,它是java程序最主要的内存工作区域,几乎所有的对象实例都存放在java堆中,堆空间是所有线程共享的。

:每个虚拟机线程都有一个私有的栈,一个线程的java栈在线程创建的时候被创建,java栈中保存局部变量、方法参数、同时java的方法调用、返回值等。

3.如何设置堆空间的大小

-Xms:堆空间的初始值

-Xmx:堆空间的最大值

原则上一般会将两个值设置为一般大,从而可以减少GC的次数

4.常用的垃圾回收算法

复制算法:其核心思想就是将内存空间分为两块,每次只使用其中一块,在垃圾回收时,将正在使用的内存中的留存对象复制到未被使用的内存块中去,之后去清除之前正在使用的内存块中所有的对象,反复去交换两个内存的角色,完成垃圾收集。(java中新生代的from和to空间就是使用这个算法)。

标记清除法:就是分为标记和清除两个阶段进行处理内存中的对象,当然这种方式也有很大弊端,就是空间碎片的问题,垃圾回收后空间是不连续的,不连续的内存空间的工作效率要低于连续的内存空间。

标记压缩法:标记压缩法是在标记清除法基础之上做了优化,把存活的对象压缩到内存一端,而后进行垃圾清理(java中老年代使用的就是标记压缩法)。

5.新生代和老年代为什么使用不同的算法

新生代GC比较频繁,回收的对象比较多,老年代则相反,经历过N多次GC都没被回收,GC次数较少!

6.主流的垃圾回收器

串行回收器、并行回收器

CMS回收器:并发标记清除,使用标记清除法,主要关注系统停顿时间。

G1回收器:属于分代垃圾回收器,区分新生代和老年代,依然有eden和from/to区,使用了分区算法

7.java 的GC 什么时候回收垃圾?
  1. 执行 system.gc()的时候
  2. 新生代对象晋升到老年代的时候,老年代剩余空间低于新生代对象晋升为老年代的速率,会触发老年代回收
  3. new 一个大对象,新生代放不下,直接到老年代,空间不够,触发Full GC
  4. 对象没有了引用的时候,下次GC就会被回收掉
### 关于 JVM 面试题的常见问题及其解析 #### 1. **JVM 内存结构** JVM 的内存主要分为堆、方法区、栈、本地方法栈以及程序计数器五个部分。其中,堆是垃圾回收的主要区域,被划分为新生代老年[^1]。 ```java // 新生代中的对象分配演示 public class ObjectAllocation { public static void main(String[] args) { byte[] allocation1, allocation2; allocation1 = new byte[2 * 1024 * 1024]; // 对象可能进入 Eden 区 allocation2 = new byte[2 * 1024 * 1024]; // 如果空间不足,则触发 Minor GC } } ``` #### 2. **GC 过程与算法** 常见的垃圾收集算法有标记-清除法、复制法、标记-整理法以及分收集法。在实际应用中,通常会采用 CMS 或 G1 收集器来优化性能[^1]。 #### 3. **类加载机制** JVM 类加载过程包括加载、验证、准备、解析和初始化阶段。双亲委派模型确保了 Java 核心库的安全性和一致性。 #### 4. **引用类型** Java 中存在四种不同的引用类型:强引用、软引用、弱引用和虚引用。这些引用类型主要用于管理内存资源并配合垃圾回收器工作[^5]。 #### 5. **Happens-Before 原则** Java 提供了一套 Happens-Before 规则以保障线程间的可见性。其中包括程序顺序规则、监视器锁规则、volatile 变量规则等八大原则[^3]。 #### 6. **循环引用问题** 即使两个对象相互持有对方的引用,在它们不再被任何外部变量引用的情况下,现垃圾回收器仍然能够识别这种关系并将两者都回收掉[^2]。 ```java // 循环引用示例 class Node { private Node next; public Node(Node n) { this.next = n; } protected void finalize() throws Throwable { System.out.println("Finalizing..."); } } public class CircularReferenceTest { public static void main(String[] args) throws InterruptedException { Node nodeA = new Node(null); Node nodeB = new Node(nodeA); nodeA.next = nodeB; // 创建循环引用 nodeB = null; nodeA = null; System.gc(); Thread.sleep(100); // 等待垃圾回收完成 } } ``` #### 7. **JVM 参数调优** 通过设置 `-Xms` 和 `-Xmx` 来指定初始堆大小和最大堆大小;利用 `-XX:+UseG1GC` 开启 G1 垃圾收集器可以有效提升大型应用程序的表现[^4]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值