重温经典《Thinking in java》第四版之第五章 初始化与清理(三十一)

简介: 重温经典《Thinking in java》第四版之第五章 初始化与清理(三十一)

“5.5.4 垃圾回收器如何工作”,这一小节重点论述了垃圾回收器的作用,以及垃圾回收器在Java中的回收技术介绍。Java语言从1995年到现在已经28年了,垃圾回收器的技术也在不断的更新迭代,可以说是更快,更高和更强了。从业这么久,没有对Java的垃圾回收器技术参数做过配置和优化,也没有排查过垃圾回收器相关的问题,很惭愧。

Java的垃圾回收器(Garbage Collector,GC)是Java运行时环境的一部分,它的主要任务是自动回收程序中不再使用的对象所占用的内存。这个过程通常是自动进行的,无需程序员显式地释放内存。垃圾回收器的工作原理主要依赖于以下几个概念:

1、对象引用:当创建一个对象并赋值给一个变量时,该变量就成为该对象的引用。当没有变量引用该对象时,该对象就被认为无法访问,因此被认为是垃圾数据。

2、根对象:在程序的执行过程中,有一些对象是全局的,或者是其他对象的成员,这些对象被称为根对象。垃圾回收器从根对象开始,找出所有被这些根对象直接或间接引用的对象,这些对象被认为是活动的,而没有被任何根对象引用的对象则被认为是垃圾。

3、垃圾回收算法:Java的垃圾回收器使用了几个经典的垃圾收集算法,包括标记-清除(Mark-Sweep)、复制(Copying)、标记-整理(Mark-Compact)和分代收集(Generational Collect)。

标记-清除算法:这是最基础的垃圾回收算法。它分为两个阶段:标记阶段和清除阶段。在标记阶段,垃圾回收器从根对象开始,标记所有可达的对象;在清除阶段,清除所有未被标记的对象。

复制算法:将内存分为两个区域,每次只使用其中一个区域。当这个区域被用满时,就遍历这个区域的所有对象,将所有可达的对象复制到另一个区域中。然后,原区域的所有对象都被认为是垃圾。

标记-整理算法:这是一种结合了标记-清除和复制的算法。在标记阶段,垃圾回收器标记所有可达的对象;在整理阶段,它将所有未被标记的对象移动到一起,并释放它们所占用的空间。

分代收集算法:这种算法基于一个观察:大多数对象很快就会变得无用,而长时间存活的对象往往比短时间存活的对象存活得更久。因此,垃圾回收器将内存分为新生代和老生代两个区域。新创建的对象首先被放在新生代中,随着它们在新生代中的存活时间变长,它们会被逐渐提升到老生代中。

4、垃圾收集器:Java提供了几个不同的垃圾收集器,包括Serial Collector、Parallel Collector、CMS(Concurrent Mark Sweep)Collector和G1(Garbage-First)Collector等。这些垃圾收集器的选择可以在Java运行时环境通过命令行参数进行配置。

 

几个不同的垃圾收集器的区别主要体现在以下几个方面:

1、运行机制:不同的垃圾收集器使用不同的运行机制。例如,Serial收集器使用单线程方式进行垃圾回收,Parallel Scavenge收集器关注点是吞吐量(高效率的利用CPU),而CMS等收集器的关注点更多的是用户线程的停顿时间(提高用户体验)。

2、回收策略:不同的垃圾收集器采用不同的回收策略。例如,Serial收集器采用标记整理算法,Parallel Scavenge收集器采用复制算法,而CMS收集器则基于标记清除算法。

3、优化重点:不同的垃圾收集器优化的重点不同。例如,Parallel Scavenge收集器关注点是吞吐量,即CPU中用于运行用户代码的时间与CPU总消耗时间的比值,而Concurrent Mark Sweep收集器则以最短回收停顿时间为目标。

4、适用场景:不同的垃圾收集器适用于不同的场景。例如,Parallel Scavenge收集器适合进行CPU密集型任务的执行,Serial收集器适合单核处理器或低延迟场景,而Concurrent Mark Sweep收集器则适用于需要较高用户响应率的交互式应用。

要想更好的了解回收算法和各种垃圾回收器,还要从Jvm的内存模型学习开始,这一块在《深入理解Java虚拟机》这本书里有详细的介绍,感兴趣的可以找来学学。

目录
相关文章
|
2月前
|
设计模式 Java 数据库连接
【重温设计模式】代理模式及其Java示例
【重温设计模式】代理模式及其Java示例
23 2
|
2天前
|
Java 编译器
【Java探索之旅】解密构造方法 对象初始化的关键一步
【Java探索之旅】解密构造方法 对象初始化的关键一步
6 1
|
2天前
|
存储 Java 编译器
【Java探索之旅】数组概念与初始化指南:动静结合
【Java探索之旅】数组概念与初始化指南:动静结合
10 0
|
9天前
|
Java
Java类 初始化顺序 | 静态数据的初始化
Java类 初始化顺序 | 静态数据的初始化
7 0
|
2月前
|
存储 Java 索引
Java数组的初始化
Java数组的初始化
12 0
|
3月前
|
缓存 Java 编译器
Java 构造函数与修饰符详解:初始化对象与控制权限
Java 构造函数 是一种特殊的类方法,用于在创建对象时初始化对象的属性。它与类名相同,并且没有返回值类型。 构造函数的作用: 为对象的属性设置初始值 执行必要的初始化操作
54 0
|
4月前
|
Java
java初始化list的几种方式
java初始化list的几种方式
21 0
|
4月前
|
设计模式 算法 Java
重温经典《Thinking in java》第四版之第九章 接口(四十七)
重温经典《Thinking in java》第四版之第九章 接口(四十七)
26 0
|
4月前
|
Java 编译器 C++
重温经典《Thinking in java》第四版之第九章 接口(四十六)
重温经典《Thinking in java》第四版之第九章 接口(四十六)
17 0
|
1天前
|
缓存 Java 调度
Java并发编程:深入理解线程池
【4月更文挑战第30天】 在Java并发编程中,线程池是一种重要的工具,它可以帮助我们有效地管理线程,提高系统性能。本文将深入探讨Java线程池的工作原理,如何使用它,以及如何根据实际需求选择合适的线程池策略。