这是我参与11月更文挑战的第17天,活动详情查看:2021最后一次更文挑战
前言
在之前的篇章我们讲了堆的架构,但是对于GC这块只有一个初步的了解,所以本篇章是为了弥补之前的内容,但在此之前我们先讲一下GC的算法,GC的算法是由始至终贯穿现在的收集器。目前市面上的收集器都是基于这三个算法而来,可能部分收集器为这三个算法的变种。
GC垃圾回收器
GC全名叫做Garbage Collection, 垃圾回收器顾名思义就是处理垃圾,但是我们要知道垃圾是如何定义的。在java虚拟机中,垃圾是在堆中不被引用的对象,垃圾要是多了会占用内存空间,导致内存空间一直增长,这显然是不合理的。在前面篇章我们也了解到了java虚拟机就是帮我们管理内存的,而他管理内存的方式离不开GC。
GC怎么知道这是个垃圾?
垃圾的定义上面已经说了,那么GC是如何知道这个是垃圾呢?在java虚拟机中GC中辨别垃圾的方法有两种,第一种引用计数法,第二种是可达性分析法。这两个是垃圾发现的两个方法。
引用计数法
引用计数法它给出的解决方案是每个对象都有个引用计数,如果对象被引用那么它就会加1,GC回收是判断他是否为0如果为0那就是垃圾会被GC回收掉。这个方法java虚拟机并没有采用,因为这个会来带一个问题,就是循坏引用的对象都是1那就永远无法清除了,但是这个方法也不是不能用,在其他语言中解决了循环引用这个问题,但是代价有点大所以Java采用了另一种
可达性分析法
可达性分析法是java虚拟机采用的方法,他没有循环引用这问题,他的实现是使用GCRoot来循环遍历对象的引用。他的结构是一颗数结构,一个GCRoot节点下有他的引用节点,依次类推展开树形结构。如果对象最后遍历不到GCRoot节点,而是独立在堆中,那么他和他引用的对象都将会在下一个GC中被回收掉。
那么那些可以当做GC root节点?
- java虚拟机栈局部变量
- 方法区静态变量、常量
- 本地方法栈 引用的对象