浅析Java内存模型与垃圾回收
1. Java内存模型
Java内存模型(Java Memory Model,JMM)定义了Java程序中线程如何与内存交互的规范。它确保了多线程环境下的可见性、有序性和原子性。
1.1 主内存与工作内存
Java内存模型中有两个重要的概念:主内存和工作内存。
- 主内存是所有线程共享的内存区域,包含了所有的变量。
- 每个线程都有自己的工作内存,工作内存是线程私有的,存储了主内存中的部分变量副本。
1.2 内存间的交互操作
Java内存模型定义了一些规则,用于控制主内存和工作内存之间的交互操作。
- 写操作:当线程对变量进行写操作时,首先将变量的值更新到自己的工作内存中,然后再将工作内存中的值刷新到主内存中。
- 读操作:当线程对变量进行读操作时,首先将变量的值从主内存中读取到自己的工作内存中,然后再使用工作内存中的值进行操作。
1.3 内存间的可见性、有序性和原子性
Java内存模型保证了以下三个特性:
- 可见性:当一个线程对变量进行写操作后,其他线程能够立即看到这个变量的最新值。
- 有序性:Java内存模型禁止指令重排序,保证了程序执行的顺序与代码的顺序一致。
- 原子性:Java内存模型提供了一些原子操作,保证了多线程环境下的原子性操作。
2. 垃圾回收
垃圾回收是Java虚拟机自动管理内存的一种机制。它通过自动回收不再使用的对象,释放内存空间,避免了手动释放内存的繁琐操作。
2.1 垃圾回收算法
Java虚拟机使用了不同的垃圾回收算法,包括标记-清除算法、复制算法、标记-整理算法等。
- 标记-清除算法:首先标记所有活动对象,然后清除未标记的对象。
- 复制算法:将内存分为两个区域,每次只使用其中一个区域,当一个区域满了之后,将存活的对象复制到另一个区域,然后清除当前区域中的所有对象。
- 标记-整理算法:首先标记所有活动对象,然后将所有活动对象向一端移动,然后清除未移动的对象。
2.2 垃圾回收器
Java虚拟机提供了不同的垃圾回收器,用于执行垃圾回收算法。
- Serial收集器:单线程执行垃圾回收,适用于小型应用。
- Parallel收集器:多线程执行垃圾回收,适用于多核处理器。
- CMS收集器:并发标记-清除算法,减少垃圾回收的停顿时间。
- G1收集器:分代收集算法,将堆内存划分为多个区域,每个区域独立进行垃圾回收。
3. 示例说明
3.1 内存可见性示例
public class VisibilityExample {
private static boolean flag = false;
public static void main(String[] args) throws InterruptedException {
new Thread(() -> {
while (!flag) {
// do something
}
System.out.println(\"Flag is now true\");
}).start();
Thread.sleep(1000);
flag = true;
}
}
在上述示例中,主线程将flag
设置为true
,但是子线程可能无法立即看到这个变化。这是因为没有使用同步机制来保证可见性。可以通过使用volatile
关键字修饰flag
变量来解决这个问题。
3.2 垃圾回收示例
public class GarbageCollectionExample {
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
for (int i = 0; i < 1000000; i++) {
list.add(i);
}
list = null; // 将list置为null,使其成为垃圾对象
// 执行垃圾回收
System.gc();
}
}
在上述示例中,当list
对象不再被引用时,将其置为null
,使其成为垃圾对象。然后通过调用System.gc()
方法执行垃圾回收,释放list
占用的内存空间。
以上是对Java内存模型与垃圾回收的浅析,希望能对你有所帮助。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:浅析Java内存模型与垃圾回收 - Python技术站