Java虚拟机学习笔记——垃圾收集器和内存分配(上)

      说起GC(Garbage Collection)大家可能都不陌生,就是对当前内存中不再使用的“垃圾”内存进行回收和释放,如果想要做好GC,首先要考虑的就是三件事:

  1. 哪些内存需要回收
  2. 应该如何回收这些内存
  3. 应该在何时回收

    在Java虚拟机中,虚拟机栈,程序计数器和本地方法栈都是线程私有的,随着线程启动和停止而分配和释放内存,这样的区域所使用的内存,几乎是可控的,所以没必要过多的考虑回收的问题。需要注意的是Java堆和方法区,这些既是线程共享而且某一个接口的实现类需要多少内存,在运行之前也无从得知,所以它们的内存分配和回收都是动态的,这也是我们要讨论的重点。众所周知,堆中几乎是保存着Java中所有的对象,要是进行内存回收,首先就要知道哪些对象是“死的”不在使用,比较普遍的判断方法是引用计数算法和根搜索算法。

  1. 引用计数算法

     其中引用计数方法就是为每个对象添加一个引用计数器,当有地方引用它的时候,计数器就+1,引用失效之后计算器就-1,认为当引用计数器为0时候,该对象不再被引用可以回收,但是算法有一个缺点或者说是不准确之处就是不能解决相互循环引用的问题,比如说现有两个对象objectA和objectB,互为成员属性于此同时再无其他引用。它们的引用计算器都为1,但是不可能成为其他的引用,这样GC又不能进行内存回收。2

    2.根搜算法

   

     在主流的商用程序语言中(Java和C#),都是使用根搜索算法(GC Roots Tracing)判断对象是否存活的。这个算法的基本思路就是通过一系列名为"GC Roots"的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链(Reference Chain),当一个对象到GC Roots没有任何引用链相连时,则证明此对象是不可用的,如图所示对象object 5、object 6、object 7虽然互相有关联,但是它们到GC Roots是不可达的,所以它们将会被判定为是可回收的对象。


   在Java语言里,可作为GC Roots对象的包括如下几种:
   a.虚拟机栈(栈桢中的本地变量表)中的引用的对象
   b.方法区中的类静态属性引用的对象
   c.方法区中的常量引用的对象
   d.本地方法栈中JNI的引用的对象    引用的分类    

猜你喜欢

转载自haomuyuiter.iteye.com/blog/2272501