GC如何判断对象是否存活
- 引用计数算法
- 可达性分析
引用计数器: 给对象添加一个引用计数器,当对象添加一个引用时计数器加1,引用失效时计数器减1,。引用计数为0的对象可被回收。
优点:快,方便,实现简单。
缺点:对象相互引用时(A.instance-B 同时 B.instance=A),很难判断是否该回收。
可达性分析:该算法根据“GC Roots”的对象作为起点,向下搜索,其路径为引用连(Reference Chain),某对象没有任何引用链时,则证明该对象不可用。
GC Roots的对象包括: - 当前虚拟机栈中局部变量表中的引用的对象
- 当前本地方法栈中局部变量表中的引用的对象
- 方法区中类静态属性引用的对象
- 方法区中的常量引用的对象
finalize:虽然可以完成对象拯救,但是JVM不一定会执行,是个“坑”。
各种引用
- 强引用 =
- 软引用 SoftReference
- 弱引用 WeakReference
- 虚引用 PhantomReference
强引用:Object obj=new Object(),就是强引用
软引用:内存充足是不会回收,内存不足时会回收,适用于缓存,一些有用但非必须的对象,进行OOM之前,就会被回收。
弱引用:无论内存是否充足,都会被回收。例如:ThreadLocal、weakHashMap
虚引用:最弱,和没有引用一样
GC (Garbage Collection)
-Xms 堆内存出事内存分配的大小
-Xmx 堆内存可被分配的最大上限
-XX:+PrintGCDetails 打印GC详情
-XX:+HeapDumpOnOutOfMemoryError 当堆内存空间溢出时打印堆内存快照
-Xmn 新生代内存分配大小
- Minor GC :发生在新生代,频繁,执行快
- Full GC :主要发生老年代(新生代也会回收),较少发生,执行速度慢
垃圾回收算法
- 复制算法(Copying)
- 标记-清除算法(Mark-Sweep)
- 标记-整理算法(Mark-Compact)
复制算法:
优点,效率高,不会出现内存碎片,
缺点,内存利用率低,只能用一半,存活对象较多时效率明显下降
Eden from to 8:1:1,java中大部分对象朝生夕死,所以只有10%的对象需要回收,10%(from)+ 10%(to,预留)
标记清除算法:
优点:空间利用率100%
缺点:标记和清除效率都不高,会产生大量不连续的内存碎片
过程:1.首先标记所有需要回收的对象 2.统一回收被标记的对象
标记整理算法:
优点:利用率100%,没有内存碎片
缺点:标记和清除效率都不高,效率相对标记-清除要低
过程:标记后不直接进行清理,而是把存活对象向一端移动,然后清理端边界外的内存。
垃圾回收器
分代算法:根据各个年代特点选用不用垃圾回收算法
新生代:采用复制算法
老年代:使用标记-整理或标记-清除算法
并行:垃圾收集的多线程同时进行
并发:垃圾收集的多线程和应用的多线程同时进行
回收器
1,Seral/Serial Old : 单线程
2,ParNew: 和Seral基本没区别,多线程
3,Parallel Scavenge(ParallerGC)/Parallel Old : 关注吞吐量的收集器,主要用于后台运算而不需要太多交互的任务。
4,CMS:一种最短停顿时间的收集器。使用标记清除算法
5,G1:jdk1.9以后推荐使用,跨越的新生代和老年代。使用标记整理和化整为零
所有新生代都是用复制算法,老年代 标记整理和标记清除
Concurrent MarkSweep(CMS):
-XX:+UseConcMarkSweepGC,应用于B/S系统服务器,重视服务的响应速度,希望系统停顿时间最短,给用户较好的体验。
垃圾回收过程:
- 初始标记:仅标记GC Roots直接关联的对象,速度快,需要停顿
- 并发标记:从GC Roots对象进行可达性分析,找到存活对象,耗时最长,不需要停顿
- 重新标记:修改并发标记期间因程序继续运作导致标记变动那一部分,需要停顿(STW),这个停顿会比初始标记长一些,但比并发标记时间短
- 并发清除:不需要停顿
优点:耗时最长的并发标记和并发清除可以与用户线程一起工作。
缺点:
1,CPU资源敏感:并发暂用CPU资源,CPU不足,效率明显降低。
2,浮动垃圾:并发清理阶段,由于用户线程继续运行产生的垃圾,CMS无法处理,需等待下一次GC处理,这部分成为“浮动垃圾”
3,会产生空间碎片:标记-清理算法会产生不连续的空间碎片G1垃圾收集器
-XX:+UseG1GC
内部布局改变
G1把堆划分多个大小相等的独立区域(Region),新生代和老年代不再物理隔离。
算法:标记-整理(humongous)和复制回收算法(survivor)。
GC模式
Young GC(回收Eden、Survivor区):选定所有年轻代的Region,通过控制年轻代个数,来控制young GC 的时间开销(复制回收算法)
Mixed GC(全部区域回收):不但选定年轻代Region还要选定老年代收益高的若干Region,进行释放。Mixed GC 不是Full GC,如果Mixed GC 跟不上程序分配内存速度,就会使用serial odl GC(Full GC)来收集整个GC heap。4G1不是Full GC。
全局并发标记
1, 初始标记:仅仅标记一下GC Roots能直接关联的对象,此阶段需要停顿线程(STW),但耗时很短。
2, 并发标记:从GC Roots开始对堆进行可达性分析,找到活对象,耗时很长,但与用户程序并行
3,最终标记:为了修正并发标记阶段因用户程序继续而导致标记产生变动的那一部分标记记录。需要停顿线程(STW),但是可并行执行。
4,筛选回收:首先对各个Region中的回收价值和成本进行排序,根据用户所期望的GC停顿时间来指定回收计划。此阶段与用户并行一起并行执行,但是因为回收一部分Region,时间是用户可控的,而且停顿用户线程能大幅度提交收集效率。
特点
1, 空间整理:不会产生内存碎片。算法为标记-整理和复制回收算法。
2, 可预测的停顿:G1,刷选不是经常使用,而是刷选那些回收效率比较高的区域(回收回报比比较高)。总共1000个区域,一个区域10m * 筛选常用的100个区域 急需回收。
Stop The World
GC收集器和GC优化的目标就是尽可能的减少STW的时间和次数。