JVM 垃圾回收笔记

来源:互联网 发布:冠新软件招聘信息 编辑:程序博客网 时间:2024/06/10 05:12

JVM垃圾收集器

GC要做的三件事:1.哪些内存(对象占用的内存)需要回收;2.什么时候回收;3.如何回收;

判断对象可回收的算法有引用计数算法和根搜索算法两种

引用计数算法:给对象添加引用计数器,引用计数器为0的时候认为不再使用,算法简单效率高但是很难解决对象相互引用的问题。

根搜索算法(JAVA、C#使用):通过GC Roots对象作为起点向下搜索,当一个对象不能通过引用链到达时认为不再使用。JAVA中GC Roots包含的对象有 1.虚拟机栈中引用的对象;2.方法区中类的静态属性引用的对象;3.方法区中常量引用的对象;4.本地方法栈(JNI)中引用的对象;

引用分为强引用、软引用、弱引用、虚引用四种。强引用指类似于“Object obj = new Object()”这种引用,只要引用还在就不会被回收;软引用描述一些还有用但是非必需的对象,内存溢出前回收这类引用的对象;弱引用指非必需的对象,下次垃圾回收时回收掉;虚引用不对生存周期产生影响,也无法通过虚引用获取对象,虚引用的目的就是回收时收到系统通知。

注:任何一个对象的finalize方法都只会被执行一次。

方法区(永久代)的回收:方法区的回收主要包括废弃常量和无用的类;常量池中的常量没有被引用;类的回收必须满足3个条件,1:该类的所有实例已经被回收;2:该类的加载器(ClassLoader)已经被回收;3、该类对应的Class对象没有在任何地方被引用。


垃圾收集算法包括标记-清除算法、复制算法、标记整理算法、分代收集算法。

1.标记-清除算法分标记和清除两个阶段,标记和清除效率都不高,另外会产生大量的内存碎片有可能触发再次GC;

2.复制算法把内存分为两块,每次使用一块,GC时把存活的对象复制到另一块内存然后清理当前使用的块,简单高效但是内存耗费较大。现代商业虚拟机都采用这种算法,不过把内存分为Eden和两块较小的Survivor空间,默认为8:1

3.标记-整理算法包括标记-整理-清除三个阶段,整理阶段是把存活的对象向一端移动。

4.分代收集算法根据对象存活周期将内存划分为几块进行收集,一般把JAVA堆分为新生代和老年代分别采用复制算法、标记清除或标记整理算法


垃圾收集器主要包括Seria收集器、ParNew收集器、Parallel Scavenge收集器、Serial Old收集器、Parallel Old收集器、CMS收集器、G1收集器

Serial收集器单线程收集器,进行回收时暂停所有线程(包括应用服务线程)

ParNew收集器是使用复制算法、并行收集器但是垃圾收集时仍然停掉服务线程,Server模式下首选新生代收集器,除了Serial收集器只有ParNew收集器能与CMS收集器共用。

Parallel Scavenge收集器也是使用复制算法、并行的收集器,与ParNew不同的是目标是达到一个可控制的吞吐量(Throughput);吞吐量=运行服务时间/(运行服务时间+垃圾回收时间),使用-XX:MaxGCPauseMillis参数设定垃圾回收时间,-XX:GCTimeRatio设定垃圾回收时间比率,如果把参数值设为19则最大GC时间为1/(1+19)=5%,默认为99。

SerialOld收集器Serial的老年版本使用标记整理算法。

ParallelOld收集器是Parallel Scavenge的老年代版,使用标记整理算法。

CMS收集器以获取最短停顿时间为目标的收集器适合用于现代的BS结构的服务器,基于标记清除算法实现。包括初始标记、并发标记、重新标记并发清除四个步骤,初始标记、重新标记仍然需要停止服务线程,初始标记标记与GCRoots直接相连的对象、并发标记用于GCRoots tracing,重新标记用于修正并发标记的结果。CMS默认启动的回收线程数是(CPU数量+3)/4



0 0
原创粉丝点击