`
从此醉
  • 浏览: 1046579 次
  • 性别: Icon_minigender_1
  • 来自: US
社区版块
存档分类
最新评论

JVM学习之:GC的算法简述

 
阅读更多

由于垃圾收集算法在各个虚拟机以及不同的平台上会有不同的实现,所以开头先大概讲解一下几个基本的算法

1. 引用计数(Reference Counting)

为每一个对象添加一个计数器,计数器记录了对该对象的活跃引用的数量。如果计数器为0,则说明这个对象没有被任何变量所引用,即应该进行垃圾收集。
收集过程如下:
1. 减少被收集对象所引用的对象的计数器的值
2.将其放入延时收集队列之中

引用计数的方法需要编译器的配合。编译器需要为此对象生成额外的代码。如赋值函数将此对象赋值给一个引用时,需要增加此对象的引用计数。还有就是,当一个引用变量的生命周期结束时,需要更新此对象的引用计数器。

引用计数的方法由于存在显著的缺点,实际上并未被JVM所使用。下面的程序可以用来证明这点:

public class ReferenceCountingGC {
	
	/**
	 * -verbose:gc -XX:+PrintGCDetails -Xms30M -Xmx30M -Xmn10M
	 */
	public static final int	    _1M	    = 1024 * 1024;
	private ReferenceCountingGC	ref	    = null;
	private byte[]	            content	= new byte [_1M * 1];
	
	public void testGC() {
		ReferenceCountingGC a = new ReferenceCountingGC();
		ReferenceCountingGC b = new ReferenceCountingGC();
		a.ref = a;
		b.ref = b;
		a = null;
		b = null;
		System.gc();
		
	}
	
	public static void main(String[] args) {
		new ReferenceCountingGC().testGC();
	}
	
}
下面为运行的结果:

[GC [PSYoungGen: 3411K->1248K(8960K)] 3411K->1296K(29440K), 0.0013584 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (System) [
PSYoungGen: 1248K->0K(8960K)] [PSOldGen: 48K->1240K(20480K)] 1296K->1240K(29440K) [PSPermGen: 2993K->2993K(21248K)], 0.0064104 secs] [Times: user=0.01 sys=0.00, real=0.01 secs]
Heap

从程序中可以看出,即使a,b两个对象通过相互引用的方式来保持对象计数器的值不为零,但是任然会被垃圾回收器进行回收(

Java -verbose:gc中参数-verbose:gc表示输出虚拟机中GC的详细情况.

运行结果解读如下:

  箭头前后的数据1248K和0K分别表示垃圾收集GC前后所有存活对象使用的内存容量,说明有1248K-0K=1248K的对象容量被回收,括号内的数据8960K为堆内存的总容量,收集所需要的时间是0.0064104秒(这个时间在每次执行的时候会有所不同)

Note:GC会暂用CPU时间片,有可能造成应用程序在某个时刻极短的停顿.

)

2.标记-清除收集器(Mark-Swap Collectors)
收集过程分为2个阶段
1. 首先停止所有工作,从根集遍历所有被引用的节点,然后进行标记,最后恢复所有工作
2. 收集阶段会收集那些没有被标记的节点,然后返回空闲链表

标记-清除法的缺点在于
1.标记阶段暂停的时间可能很长,而整个堆在交换阶段又是可访问的,可能会导致被换页换出内存。
2.另外一个问题在于,不管你这个对象是不是可达的,即是不是垃圾,都要在清楚阶段被检查一遍,非常耗时.

3,标记清楚这两个动作会产生大量的内存碎片,于是当有大对象进行分配时,不需要触发一次垃圾回收动作

3.拷贝收集器(Copying Collectors)(适用于young generation:PSYoungGen)

该算法的提出是为了克服句柄的开销和解决堆碎片的垃圾回收。
将内存分为两个区域(from space和to space)。所有的对象分配内存都分配到from space。在清理非活动对象阶段,把所有标志为活动的对象,copy到to space,之后清楚from space空间。然后互换from sapce和to space的身份。既原先的from space变成to sapce,原先的to space变成from space。每次清理,重复上述过程。

现在的商业虚拟机都用这种算法来回收新生代,因为新生代的大多数的生命周期都很短暂,所以前面提到的两块相互切换的区域并不需要按照1:1来进行分配。而是分配了一个Eden区,两个Survivor区。大部分对象默认的都是在 Eden区中生成。当垃圾回收时,Eden和其中的一个Survivor区的存活对象将被复制到另外一个Survivor区,当另外一个Survivor区也满了的时候,从Eden和第一个Survivor区复制过来的并且此时还存活的对象,将被复制到tenured generation。需要注意,Survivor的两个区是对称的,没先后关系,所以同一个区中可能同时存在从Eden复制过来对象,和从前一个Survivor复制过来的对象,而复制到年老区的只有从第一个Survivor去过来的对象。而且,Survivor区总有一个是空的。
young generation的gc称为minor gc。经过数次minor gc,依旧存活的对象,将被移出young generation,移到tenured generation

优点:copy算法不理会非活动对象,copy数量仅仅取决为活动对象的数量。并且在copy的同时,整理了heap空间,即,to space的空间使用始终是连续的,内存使用效率得到提高。
缺点:默认情况下Eden:Survivor=8:1, 所以总会有100-(80+10)%的新生代内存会被浪费掉。

4.标记-整理收集器(Mark-Compact Collectors)(适用于存放生命周期较长对象的tenured generation:PSOldGen)
标记整理收集器,通过融合了标记-清除收集器和拷贝收集器的优点,很好的解决了拷贝收集策略中,堆内存浪费严重的问题。

标记整理收集器分为2个阶段
1. 标记阶段, 这个阶段和标记-清除收集器的标记阶段相同
2. 整理阶段, 这个阶段将所有做了标记的活动对象整理到堆的底部(有点像是磁盘碎片整理,呵呵)

生命周期较长的对象,归入到tenured generation。一般是经过多次minor gc,还 依旧存活的对象,将移入到tenured generation。(当然,在minor gc中如果存活的对象的超过survivor的容量,放不下的对象会直接移入到tenured generation)tenured generation的gc称为major gc,就是通常说的full gc。由于tenured generaion区域比较大,而且通常对象生命周期都比较长,所以这部分的gc时间比较长。
minor gc可能引发full gc。当eden+from space的空间大于tenured generation区的剩余空间时,会引发full gc。这是悲观算法,要确保eden+from space的对象如果都存活,必须有足够的tenured generation空间存放这些对象。


最后补充一点,如果采用的是分代算法的话还会有一个permanent generation(PSPermGen)区域,该区域比较稳定,主要用于存放classloader信息,比如类信息和method信息。
对于spring hibernate这些需要动态类型支持的框架,这个区域需要足够的空间。(这部分空间应该存在于方法区而不是heap中)。



分享到:
评论

相关推荐

    高级开发jvm面试题和答案.pdf

    面试高级开发的期间整理的面试题目,记录我...gc算法; gc种类: 简述一下内存溢出的原因,如何排查线上问题? 内存溢出的原因 引用在gc中回收状况 为什么gc停止所有进程; 有几种垃圾回收器; 描述一下CMS和G1的异同;

    万得信息技术Java开发面经.pdf

    1.JVM 垃圾清理过程,GC算法 2.⼋⼤排序算法以及时间空间复杂度 3.JUC 锁:写⼊锁 只读锁 4.ArrayList LinkedList区别 5.MongoDB使⽤ 6.zk能做什么 7.场景题:集群服务器宕机解决⽅案 8.MongoDB和redis区别,分别...

    java面试题,180多页,绝对良心制作,欢迎点评,涵盖各种知识点,排版优美,阅读舒心

    【JVM】JVM内存结构,GC垃圾收集解析 52 【JVM】双亲委派模型中,从顶层到底层,都是哪些类加载器,分别加载哪些类? 55 【JVM】能不能自己写个类叫java.lang.System? 57 【JVM】类的加载过程 58 【JVM】类的初始化...

    net学习笔记及其他代码应用

    1. 简述 private、 protected、 public、 internal 修饰符的访问权限。 答 . private : 私有成员, 在类的内部才可以访问。 protected : 保护成员,该类内部和继承类中可以访问。 public : 公共成员,完全公开,...

    最新Java面试宝典pdf版

    75、描述一下JVM加载class文件的原理机制? 52 76、heap和stack有什么区别。 52 77、GC是什么? 为什么要有GC? 52 78、垃圾回收的优点和原理。并考虑2种回收机制。 52 79、垃圾回收器的基本原理是什么?垃圾回收器可以...

    超级有影响力霸气的Java面试题大全文档

    Hashtable和HashMap采用的hash/rehash算法都大概一样,所以性能不会有很大的差异。 15、final, finally, finalize的区别。  final 用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。 ...

    Java面试笔试资料大全

    75、描述一下JVM加载class文件的原理机制? 52 76、heap和stack有什么区别。 52 77、GC是什么? 为什么要有GC? 52 78、垃圾回收的优点和原理。并考虑2种回收机制。 52 79、垃圾回收器的基本原理是什么?垃圾回收器可以...

    Java面试宝典2010版

    75、描述一下JVM加载class文件的原理机制? 76、heap和stack有什么区别。 77、GC是什么? 为什么要有GC? 78、垃圾回收的优点和原理。并考虑2种回收机制。 79、垃圾回收器的基本原理是什么?垃圾回收器可以马上回收...

    java面试题大全(2012版)

    75、描述一下JVM加载class文件的原理机制? 52 76、heap和stack有什么区别。 52 77、GC是什么? 为什么要有GC? 52 78、垃圾回收的优点和原理。并考虑2种回收机制。 52 79、垃圾回收器的基本原理是什么?垃圾回收器可以...

    JAVA面试题最全集

    描述一下JVM加载class文件的原理机制? 41.试举例说明一个典型的垃圾回收算法? 42.请用java写二叉树算法,实现添加数据形成二叉树功能,并以先序的方式打印出来. 43.请写一个java程序实现线程连接池功能? 44...

    Java面试宝典-经典

    75、描述一下JVM加载class文件的原理机制? 52 76、heap和stack有什么区别。 52 77、GC是什么? 为什么要有GC? 52 78、垃圾回收的优点和原理。并考虑2种回收机制。 52 79、垃圾回收器的基本原理是什么?垃圾回收器可以...

    JAVA面试宝典2010

    75、描述一下JVM加载class文件的原理机制? 52 76、heap和stack有什么区别。 52 77、GC是什么? 为什么要有GC? 52 78、垃圾回收的优点和原理。并考虑2种回收机制。 52 79、垃圾回收器的基本原理是什么?垃圾回收器可以...

    Java面试宝典2012版

    75、描述一下JVM加载class文件的原理机制? 52 76、heap和stack有什么区别。 52 77、GC是什么? 为什么要有GC? 52 78、垃圾回收的优点和原理。并考虑2种回收机制。 52 79、垃圾回收器的基本原理是什么?垃圾回收器...

    java面试宝典2012

    75、描述一下JVM加载class文件的原理机制? 56 76、heap和stack有什么区别。 57 77、GC是什么? 为什么要有GC? 57 78、垃圾回收的优点和原理。并考虑2种回收机制。 57 79、垃圾回收器的基本原理是什么?垃圾回收器可以...

    Java面试宝典2012新版

    75、描述一下JVM加载class文件的原理机制? 52 76、heap和stack有什么区别。 52 77、GC是什么? 为什么要有GC? 52 78、垃圾回收的优点和原理。并考虑2种回收机制。 52 79、垃圾回收器的基本原理是什么?垃圾回收器可以...

    java 面试题 总结

    Hashtable和HashMap采用的hash/rehash算法都大概一样,所以性能不会有很大的差异。 12、final, finally, finalize的区别。  final 用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。 ...

    Java 面试宝典

    16、下面的代码有什么不妥之处? ............................................................................... 14 17、请说出作用域 public,private,protected,以及不写时的区别 ...........................

Global site tag (gtag.js) - Google Analytics