我们知道程序计数器、虚拟机栈、本地方法栈三个区域都是线程私有的,它们的生命周期都是随着线程而生,随着线程而亡,因此是不需要过多考虑回收的问题,而Java Heap(堆)Method Area(方法区)不一样,必须考虑内存回收问题。

我们只有当程序运行的时候才会知道会创建哪些类,而这些类占用内存也是不同的,不会固定,都是动态的,即这部分的内存的分配与回收都是动态的,垃圾收集器关注的就是这部分内存

  VM判断对象是否死亡主要有两种方式,一种是通过计数器的方式,另外一种是通过引用链(根搜索算法):

1、计数器方式

  这是很多教科书是提及到的方法,可以算是经典的一种方式。

  (1)原理:通过引用一个计数器,每次对象被引用就会加1,当引用失败后,自然减1...如此下去,直到计数器为0(其实任何时刻都可能为0),那么可以认为此对象不可能再被引用了,也就是达到GC的条件。

  (2)优点:简单容易实现,判断效率也高,计数器的操作并不占用过多资源。

  (3)缺点:那很明显就是无法解决对象之间的循环引用问题,至于什么是对象之间的循环引用,可以通过下面的代码理解:

    

private Object instance = null;

GCObject ojbA = new Object();
GCObject ojbB = new Object();
//对象之间的循环引用
objA.instance = objB;
objB.instance = objA;
//两个对象已经不能被引用
objA = null;
objB = null;
//这里开始GC
system.gc();
View Code

相关文章: