DBMNG数据库管理与应用

抓住自己最有兴趣的东西,由浅入深,循序渐进地学……
当前位置:首页 > 经验分享 > Java开发

性能优化-监控-垃圾收集器

1.垃圾收集算法 
1)引用计数法。 
对于一个对象A,只要有任何一个对象引用了A,则A的引用计数器加1,当引用失效时,A的引用计数器减1。只要对象A的引用计数器值为0,则对象A就不能再被引用了。 
但是引用计数器无法处理循环引用的问题,所以JVM不使用引用计数法进行垃圾回收。 



2)标记-清除算法 
分为两个阶段:标记阶段和清除阶段。标记阶段从根节点标记所有可达对象。清除阶段清除所有未被标记的对象。



标记-清除算法,回收后内存空间是不连续的。 

3)复制算法 
将内存空间分为2块,每次只使用其中一块,在垃圾回收时,将正使用的内存中的存活对象复制到未使用的内存块中,之后,清除正在使用的内存块的所有对象,交换两个内存的角色。 



复制算法适用于新生代垃圾收集,因为新生代大部分对象都是垃圾对象,所以采用复制算法效率比较高。 
复制算法的代价是内存被减少了一半。 
4)标记-压缩算法 
标记-压缩算法和标记-清除算法类似,但是它并不是简单的清除垃圾对象,而是将存活对象都压缩到内存的一端。 
标记-压缩算法避免了内存碎片的产生。 



由于老年代大部分是存活对象,所以不适合复制算法,而比较适合此算法。 

以上各种算法,以及下面将介绍的垃圾收集器没有一个放之四海而皆准的,只有适合不适合,每个都有适合的场景,否则其他算法和垃圾收集器也就没有存在的必要了。 

2.垃圾收集器 
大部分垃圾收集器,垃圾回收过程中,应用软件处于stop-the-world状态,即应用程序的所有线程挂起,暂停一切工作,等待垃圾收集完成。 

1)串行收集器。 
有2个特点:a.使用单线程进行垃圾收集。   b.它是独占式垃圾收集。 



适用于单CPU和内存较小的硬件平台。 
2)并行收集器 
它将串行收集器多线程化,从而提高垃圾收集速度。 



并行收集器主要关注系统的吞吐量。 

3)CMS收集器 
CMS是Concurrent Mark Sweep的缩写,意为:并发标记清除。 



它分为初始标记、并发标记、重新标记、并发清理、并发重置5个阶段,其中初始标记和重新标记阶段是独占系统资源的,其他阶段可以和用户线程一起执行。 

CMS收集器由于采用标记-清除算法,因此会造成内存碎片化,如果回收到足够的空间之前,老年代满了,就会退而求其次,使用代价昂贵的stop-the-world方式进行空间压缩。 

CMS收集器由于在标记时,垃圾收集和用户程序交替执行,因此用户程序会继续分配内存,所以CMS垃圾收集器需要更大的堆。 

CMS收集器主要关注响应性,它减少了延迟,同时也降低了吞吐量,因为整体的垃圾收集时间被延长了。 
3.并行和并发 
系统有多个CPU,可以同时执行多个线程称为并行。多个应用程序同时交替运行称为并发。因此单CPU也可以并发,但是不能并行。 
4.GC日志 
开启-verbose:gc或者-XX:+PrintGCDetails将打印GC日志。 

1)GC 
[GC [PSYoungGen: 24201K->1952K(28288K)] 24201K->1952K(92928K), 0.0029127 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 

标签GC 说明这是一个Minor GC,PSYoungGen说明新生代使用的是多线程垃圾收集器Parallel Scavenge(-XX:+UseParallelGC或者-XX:+UseParallelOldGC). 
->左边的24201k是垃圾收集前新生代的占用量,->右边的1952k是新生代垃圾收集后的占用量。由于新生代进一步分为Eden和2块Survivor,因为Minor GC后Eden为空,所以此处的1952k也是Surivor的占用量。括号中的28288k是新生代容量的总和。 
24201K->1952K(92928K)是垃圾收集前后Java堆的使用情况。->左边的24201k是垃圾收集前Java堆的占用量,->右边的1952k是垃圾收集后Java堆的占用量。括号中的92928k是Java堆的总量(新生代+老年代)。0.0029127 secs是垃圾收集花费的时间。 
[Times: user=0.00 sys=0.00, real=0.00 secs]是CPU的使用时间。 

2)Full GC 
[Full GC (System) [PSYoungGen: 1632K->0K(11968K)] [PSOldGen: 2141K->3524K(27328K)] 3773K->3524K(39296K) [PSPermGen: 17590K->17590K(35712K)], 0.0457642 secs] [Times: user=0.05 sys=0.00, real=0.05 secs] 
Full GC说明这是一个Full GC垃圾收集,PSOldGen说明是老年代垃圾收集,->左边的2141K是垃圾收集前老年代的占用量,->之后的3524k是垃圾收集后老年代的占用量,占用量有增加说明有些对象从新生代晋升到了老年代,括号内的27328K是老年代的总占用量。其余同Minor GC。PSPermGen指的是永久代。 

3)Full GC (System) 
[Full GC (System) [PSYoungGen: 1648K->0K(11968K)] [PSOldGen: 2217K->3560K(27328K)] 3865K->3560K(39296K) [PSPermGen: 17590K->17590K(35712K)], 0.0578854 secs] [Times: user=0.06 sys=0.00, real=0.06 secs] 
Full GC之后的(System)表明是System.gc()导致的Full GC。 

5.各种垃圾收集器的GC日志 
1)-XX:+UseSerialGC 
新生代:DefNew 
老年代:Tenured 
永久代:Perm 
2)-XX:+UseParNewGC 
新生代:ParNew 
老年代:Tenured 
永久代:Perm 
3)-XX:+UseParallelGC 
新生代:PSYoungGen 
老年代:PSOldGen 
永久代:PSPermGen 
4)-XX:+UseParallelOldGC 
新生代:PSYoungGen 
老年代:ParOldGen 
永久代:PSPermGen 
5)-XX:+UseConcMarkSweepGC 
新生代:ParNew 
老年代:CMS 
永久代:CMS Perm 


参考资料: 
1.葛一鸣《Java性能优化》 
2.《Java性能优化权威指南》 
本站文章内容,部分来自于互联网,若侵犯了您的权益,请致邮件chuanghui423#sohu.com(请将#换为@)联系,我们会尽快核实后删除。
Copyright © 2006-2023 DBMNG.COM All Rights Reserved. Powered by DEVSOARTECH            豫ICP备11002312号-2

豫公网安备 41010502002439号