新的一年撸起袖子继续干!
什么是垃圾:
垃圾就是不在使用的,放着站空间的对象,如放在工位的矿泉水瓶...,放到jvm中也就是在内存中已经不在使用的对象,这些无用的对象就是垃圾。
那么怎么判断这些对象是垃圾呢:
jvm提供了两种算法来识别垃圾,第一是引用计数器,第二是GCROOT可达性分析。
一:引用计数器:
描述:jvm给每个对象都增加了一个计数器,存放到对象头部,当一个对象(A)被其他对象引用后,该对象(A)的引用计数器就加一,N个对象引用的话引用计数器的数为N,当一个对象不再引用该对象(A)的时候,引用计数器就会减一,当没有对象引用,引用计数器的值也就是变为0,这个时候该对象就变成了了垃圾。
优点:
简单,效率高
缺点:
会导致循环引用问题,
/**
* 会引起循环引用问题,造成应该是垃圾的无法标记出来
*/
public class YYCountGC {
private Object instance;
public static void main(String[] args){
YYCountGC y1 = new YYCountGC();
YYCountGC y2 = new YYCountGC();
y1.instance = y2;
y2.instance = y1;
y1 = null;
y2 = null;
}
二:GCROOT可达性分析:
GCROOT可达性分析是对引用计数器的补充,不会存在循环引用问题。
使用如下图片来解读:
描述:
GC Root为根节点,从根节点向下找,和根节点有链接(引用)的对象成为存活对象,向下找的链成为引用链。只要对象和GCRoot对象有引用链的都是存活对象,和GCRoot没有任何链接的称为“垃圾”,也就是可回收对象,在上图中A/B都是存活对象,C/E/F/G对象都是可回收对象。
那么什么对象可以是CGRoot对象呢?
那些对象可充当GCRoot对象呢?
1.虚拟机栈中的局部变量表:线程每进入方法和出方法称为出栈和入栈,每个方法代表一个栈,栈中包含一个栈帧,栈帧中存放局部变量表中引用的对象。
2.方法区的常量 方法使用final修饰的变量引用的对象。
3.方法区的静态变量 使用static修饰的变量引用的对象
4.native修饰的方法 这个jdk中很多,如:Unsafe
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。