垃圾回收机制
掌握 GC 算法之前,我们需要先弄清楚 3 个问题。第一,回收发生在哪里?第二,对象在
什么时候可以被回收?第三,如何回收这些对象?
回收发生在哪里?
JVM 的内存区域中,程序计数器、虚拟机栈和本地方法栈这 3 个区域是线程私有的,随着
线程的创建而创建,销毁而销毁;栈中的栈帧随着方法的进入和退出进行入栈和出栈操作,
每个栈帧中分配多少内存基本是在类结构确定下来的时候就已知的,因此这三个区域的内存
分配和回收都具有确定性。
那么垃圾回收的重点就是关注堆和方法区中的内存了,堆中的回收主要是对象的回收,方法
区的回收主要是废弃常量和无用的类的回收。
.对象在什么时候可以被回收?
那 JVM 又是怎样判断一个对象是可以被回收的呢? 一般一个对象不再被引用,就代表该对
象可以被回收。 目前有以下两种算法可以判断该对象是否可以被回收。
象被引用,引用计数器就会加 1;每当引用失效,计数器就会减 1。当对象的引用计数器的
值为 0 时,就说明该对象不再被引用,可以被回收了。这里强调一点,虽然引用计数算法
的实现简单,判断效率也很高,但它存在着对象之间相互循环引用的问题。
加载时,会创建一些普通对象引用正常对象。这些对象作为正常对象的起始点,在垃圾回收
时,会从这些 GC Roots 开始向下搜索,当一个对象到 GC Roots 没有任何引用链相连
时,就证明此对象是不可用的。目前 HotSpot 虚拟机采用的就是这种算法。
以上两种算法都是通过引用来判断对象是否可以被回收。在 JDK 1.2 之后,Java 对引用的
概念进行了扩充,将引用分为了以下四种:
![](https://i-blog.csdnimg.cn/direct/f257729ab56f4dec93fa631633cee26b.png)
GC 算法
以下几种:
![](https://i-blog.csdnimg.cn/direct/6e5b8cd80aaf474e80a4473f6292cd4c.png)
如果说收集算法是内存回收的方法论,那么垃圾收集器就是内存回收的具体实现,JDK1.7
update14 之后 Hotspot 虚拟机所有的回收器整理如下(以下为服务端垃圾收集器):
![](https://i-blog.csdnimg.cn/direct/8a48742b21d94da897e40831434aa7ae.png)
其实在 JVM 规范中并没有明确 GC 的运作方式,各个厂商可以采用不同的方式实现垃圾收
集器。 我们可以通过 JVM 工具查询当前 JVM 使用的垃圾收集器类型, 首先通过 ps 命令查
询出经常 ID,再通过 jmap -heap ID 查询出 JVM 的配置信息,其中就包括垃圾收集器的
设置类型。
查看 & 分析 GC 日志
已知了性能衡量指标,现在我们需要通过工具查询 GC 相关日志,统计各项指标的信息。
首先,我们需要通过 JVM 参数预先设置 GC 日志,通常有以下几种 JVM 参数设置:
java">1 -XX:+PrintGC 输出 GC 日志
2 -XX:+PrintGCDetails 输出 GC 的详细日志
3 -XX:+PrintGCTimeStamps 输出 GC 的时间戳(以基准时间的形式)
4 -XX:+PrintGCDateStamps 输出 GC 的时间戳(以日期的形式,如 2013-05-04T21:53:59.234+0800)
5 -XX:+PrintHeapAtGC 在进行 GC 的前后打印出堆的信息
6 -Xloggc:../logs/gc.log 日志文件的输出路径
笔者推荐文章
- 敏捷架构的 TOGAF 层次化迭代建模
- 架构规划之如何划分任务边界?
- 资源下载 技术架构,业务架构,数据架构,企业架构,行业技术方案 TOGAF | 跟着Byte学架构
- 定制化企业架构元模型-CSDN博客
- G1相对于CMS的的优势-CSDN博客