前言
垃圾回收器需要回收内存中的数据,以便保持内存一直处于可用状态。但是垃圾回收如何选择哪些数据对象需要回收,哪些不需要回收?主要是使用引用计数法及引用状态来决定是否需要回收该对象数据
第一 引用计数法
主要使用内存中的程序计数器,来对对用的引用个数计数。当对象的引用个数小于1,那么该对象可能被回收,对象是否被回收该方法只是一种参考
第二 引用状态
强引用: 直接new 类的实例,该对象不会被回收
软引用: 在内存不足,爆出内存溢出前回收
弱应用: 在一下次垃圾回收之前回收
虚应用: 随时可能回收
一、垃圾回收算法
标记+清除算法: 先将要回收的对象做好标记,然后统一进行清除,但是该处理算法会产生内存碎片
复制算法: 内存分为两部分,先使用一部分,当这一部分使用满后,将存活的对象复制到另一个未使用的内存中,然后清除复制后的内存。
该回收算法主要用于内存新生区,但是在新生区并不是1:1进行划分,而是划分三部分,eden,survivor,survivor,。其中占比为8:1:1,使用eden和一个survivor.。但使用满后,拷贝到没有使用的survivor中。当存活对象超过survivor时,这个时候会借助老生区。当该内存存活率比较高的时候使用该算法,效率会比较低。
标记+整理算法: 将存活的对象往一边移动,然后清除边界之外的对象,适用于老年代内存区。
二、垃圾收集器
1.serial收集器(串行收集器)
单线程的收集器,意味着当垃圾回收器执行的时候,会阻塞其它的线程,即“”STOP THE WOLD“”,STW。在单个CPU环境下使用该收集器,可以避免多线程切换带来的开销。
年轻代:serial收集器,使用复制算法
老年代:serial old收集器,使用复制整理算法
2. ParNew收集器
serial收集器的多线程版本。平常和CMS合用。-XX:ParallelGCThreads参数来限制垃圾收集的线程数。该收集器没有老年代的版本,需要和其它收集器联合使用。
年轻代: parknew收集器 ,使用复制算法
老年代:serial old收集器 ,使用复制整理算法
3. Parallel Scavenge收集器
多线程收集器,主要关注的是吞吐量,在单位运行时间内,更小的时间运行垃圾回收器。在新生代和老年代都是多线程的。
年轻代:Parallel Scavenge收集器,采用复制算法
老年代:Parallel Old收集器,采用标记整理算法。
-XX:+UseAdaptiveSizePolicy :自适应调节模式
4.CMS收集器
获取最短的停顿时间为目标的收集器(减少其它线程的阻塞时间)。适用于用户交互的时候。该算法使用的时标记清除算法,所以会出现内存碎片。一般回用于老年代,需要和其它的回收器联合使用。
在使用CMS的时候特别的注意的是内存碎片,所以需要注意以下两个设置,从而减少内存碎片,一个是开启老年代的内存压缩,第二个是多少次fullGC后开启内存压缩。
XX:+UseCMSCompactAtFullCollection收集开关参数(默认就是开启的),用于在CMS收集器进行FullGC完开启内存碎片的合并整理过程。会导致stw时间过长
XX:CMSFullGCsBeforeCompaction参数用于设置执行多少次不压缩的FULL GC后跟着来一次带压缩的(默认值为0,表示每次进入Full GC时都进行碎片整理)。
5.G1收集器
并行和并发,更少的停顿时间。适用于整个堆内存。使用的时标记整理算法。在内存比较大的时候比较适用。
三、GC的相关参数
-Xms: 初始化堆内存大小
-Xmx : 堆内存最大值
-Xmn: 新生代的大小
-Xss: 栈的大小
-PretenureSizeThreshold: 直接晋升到老年代的对象大小,设置这个参数后,大于这个参数的对象将直接在老年代分配。
-UseAdaptiveSizePolicy: 新生代默认是划分为三部分,一个Eden,两个servivor,默认比值是8:1:1.但是在正式使用的时候往往需要不断的调整和优化,这个是比较困难和麻烦的,开启这个参数,jvm会自动优化调整。
Full GC: full Gc是堆发生内存回收,此时整个应用程序的停顿时间比较长,一般触发fgc在以下几个情况:1.老年代内存满了,2.调用system.gc,3持久代内存满了。
网友评论