JVM是Java虚拟机(Java Virtual Machine)的缩写,它是一个能够运行Java字节码的虚拟计算机。JVM是Java平台的一部分,它提供了平台独立性,即Java程序可以一次编写,在任何支持JVM的操作系统上运行。
JVM主要有以下功能:
- 加载代码:JVM加载编译好的字节码文件(.class 文件)并将其转换为内存中的类。
- 验证字节码:JVM会验证字节码,确保它遵循Java规范,并不会破坏系统安全。
- 执行字节码:JVM通过解释或即时编译(JIT)执行字节码。
- 内存管理:JVM负责管理堆内存和栈内存,包括垃圾回收和内存分配。
- 提供运行时环境:JVM提供Java程序执行所需的运行时环境,包括线程管理、异常处理等。
Java虚拟机(JVM)使用垃圾回收机制(GC)来管理内存。当对象不再被使用时,它们会被标记为垃圾对象,并最终被回收。JVM使用几个不同的算法来判断一个对象是否可以被回收,以下是常见的一些判断标准:
一、引用计数法(已被JVM弃用)
原理:给每个对象添加一个引用计数器。每当对象被引用时,计数器加1;引用失效时,计数器减1。计数器为0时判定对象可回收。
缺陷:无法解决循环引用问题。若对象A和B互相引用,即使它们与GC Roots断开,计数器仍非0,导致内存泄漏。
示例代码:
class Node {
Node next;
public Node() {
this.next = null;
}
}
public class ReferenceCountingExample {
public static void main(String[] args) {
Node a = new Node();
Node b = new Node();
a.next = b; // a引用b(a的计数器+1)
b.next = a; // b引用a(b的计数器+1)
a = null; // 将a与根引用断开,但a和b的计数器仍为1
b = null; // 继续断开,但对象无法被回收
System.gc(); // 手动触发垃圾回收(无效)
}
}
结果:a和b的计数器始终为1,无法被回收
二、可达性分析算法(JVM实际采用)
原理:从GC Roots(如栈帧局部变量、静态变量、线程对象等)出发,遍历对象引用链。然后以GC ROOT作为起始节点, 从这些节点开始向下搜索,去寻找它的直接和间接引用的对象,当遍历完之后如果发现有一些对象不可 到达,那么就认为这些对象已经没有用了,无法从GC Roots到达的对象判定为可回收。在垃圾回收的时候,JVM会首先找到所有的GC root,这个过程会暂停所有用户线程,然后再从GCRoots这些根节点向下搜索,可达的对象保留,不可达的就会 回收掉
优势:彻底解决循环依赖问题。
可达性分析是目前主流JVM使用的算法。
示例代码
public class ReachabilityAnalysisExample {
public static void main(String[] args) {
Object obj1 = new Object(); // obj1是GC Root局部变量
Object obj2 = new Object();
obj1 = obj2; // obj1原引用对象A断开,对象A不可达
System.gc(); // 对象A被回收
}
}
// 对象A被回收
}
}
[外链图片转存中...(img-tTrLafUK-1741138361909)]
**说明**:当`obj1`指向`obj2`时,原对象A无法通过GC Roots到达,被标记为可回收