Java垃圾回收器

1、什么事垃圾回收

#C/C++语言的垃圾回收

1)在C/C++语言中,没有自动垃圾回收机制,是通过new关键字申请内存资源,通过delete关键字释放内存资源

2)如果程序员在某些位置没有写delete进行释放,那么申请的对象将一直占用内存资源,最终可能会导致内存溢出

#java语言的垃圾回收

1)Java语言中,有自动的垃圾回收机制,也就是我们熟悉的GC

2)GC精髓在于算法,如果算法不合理一样会内存溢出

2、垃圾回收的常见算法

#引用计数法

1)原理

假设有一个对象A,任何一个对象对A的引用,name对象A的引用计数器+1,当引用失败时候,对象A的引用计数器就-1,如果对象A的计数器值为0,就说明对象A没有引用了,可以被回收

2)优点

1、实时性较高,无须等到内存不够的时候,才开始回收,运行时候根据对象的计数器是否为0,就可以直接回收。

2、在垃圾回收过程中,应用无需挂起,如果申请内存时,内存不足,则立刻报outofmemory错误

3、区域性,更新对象的计数器时候,只影响到该对象,不会扫描全部对象

3)缺点

1、每次对象被引用的时候,都需要去更新计数器,有一点时间开销

2、浪费CPU资源,即使内存不够用,仍然在运行时候进行计数器的统计

3、无法解决循环引用问题(最大的缺点)

#标记清除法

1)标记清除算法是将垃圾回收分为2个阶段,分别是标记和清除

标记:从根节点开始标记引用的对象

清除:未被标记引用的对象就是垃圾对象,可以被清除

2)优点

标记清除算法解决了引用计数算法中的循环引用的问题,没有从root节点引用的对象都会被回收

3)缺点

1、效率较低,标记和清除两个动作都需要遍历所有对象,并且在GC时候,需要停止应用程序,对于交互性要求比较高的应用而言,这个体验非常差的

2、通过标记清除算法清理出来的内存,碎片化较为严重,因为被回收的对象可能存在于内存的各个角落,所以清理出来的内存是不连贯的

#标记压缩算法

1)原理

把所有使用的内存空间进行压缩排序移动,使得碎片空间完成变成完整的

#复制算法(初始的时候会开辟两个内存区域)

1)原理

S0如果内存空间放不下了,就开始触发GC操作,是的GC清理内存空间,然后把所有剩余对象空间按照顺序拷贝到S1

2)优点

1、在垃圾对象多的情况下,效率较高

2、清理后,内存无碎片

3)缺点

1、在垃圾对象少的情况下,不适用,如:老年代内存

2、分配的2块内存空间,在同一时刻,只能使用到一半,内存使用率较低

#分代算法

1)原理

根据回收对象的特点进行选择,在jvm中,年轻代适合使用复制算法,老年代适合使用标记清除或者标记压缩算法

#垃圾收集器的种类

1)Serial(串行垃圾收集器,GC线程只有一个,GC回收的时候要停止业务线程)

#串行垃圾收集器是最基本、发展历史最悠久的收集器

#特点;单线程、简单高效(与其他收集器的单线程相比),对于限定单个CPU的环境来说,Serial收集0器由于没有线程交互的开销,专心做垃圾收集自然可以获得最高的单线程收集效率,收集器进行垃圾回收时,必须暂停其他所有工作线程,直到它结束(Stop The World)

2)Parallel(并行垃圾收集器,GC线程有多个,但是只是在回收的时候多了处理收集器,还是需要停止业务线程,只是因为并行业务停止时间缩短了)主要使用场景,大数据做科学计算的

#并行垃圾收集器在串行垃圾收集器的基础之上做了改进,将单线程改成多线程垃圾回收,这样可以缩短垃圾回收的时间

#ParNew垃圾收集器

通过-XX:+UseParNewGC参数设置年轻代使用ParNew回收器,老年代使用的依然是串行收集器

通过-XX:+ParalelGCThreads可以限制GC线程使用数量,默认开启和CPU数目相同的线程数

只在新生代起作用,新生代使用并行垃圾处理器,老年代使用串行垃圾处理器

#并行垃圾收集器-ParallelGC运行示意图(吞吐量优先收集器)

新生代老年的并行化,可控制的吞吐量,高效率的高吞吐量,资源占用率比较高,这个收集器比ParNew更高端点,会自动分配调准参数

3)CMS

#CMS全称Concurrent Mark Sweep,是一款并发的、使用标记0清除算法的垃圾回收器,该回收器是针对老年代垃圾回收的,通过参数-XX:+UseConcMarkSweepGC进行设置

以获取回收停顿时间为目标的回收器。

注意:开启后将采用ParNew + CMS + Serial Old(默认启动这个串行垃圾回收器,是最后的担保机制启动后使用的,因为ConcMarkSweep这个回收线程和应用线程同时执行的,有可能出现垃圾回收没有执行完成,业务有需要内存从而内存溢出。进行保底)收集器组合

#CMS垃圾回收器的执行过程如下(回路):

1、idling(闲置等待)

2、InitialMarking(初始化标记)

3、Marking(并发标记)

4、Precleaning AbortablePreclean(预处理)

5、FinalMarking(重新标记)

6、Sweeping(并发清理)

7、Resizing(调整堆大小)

8、Resetting(重置)

#优点

并发高效,停顿间隔短,无差别停顿业务线程

#缺点

资源利用率高,容易形成空间碎片,不是实时进行清理

4)G1

#G1垃圾收集器在JDK1.7update4中正式使用的全新的垃圾收集器,oracle官网在jdk9中将G1变成默认的垃圾收集器,以替代CMS。

#G1垃圾收集器(将新生代,老年代的物理空间划分取消了),G1垃圾收集器(G1算法将堆划分为若干个区域-Region),每块区域大小默认32M,最大设置2048个区域,总共64G内存,肯定够用了

Eden,Survivor,Old,Humongous(超大区域)

#G1垃圾回收模式:

1、Young GC(年轻GC回收模式)

2、Mixed GC(混合GC回收模式)

1)全局并发标记(global concurrent marking)

2)拷贝存活对象(evacuation)

3、G1垃圾收集器相关参数

-XX:+UseG1GC

-XX:+MaxGCPauseMillis(指定垃圾回收的暂停时间,程序只能尽量按照这个时间进行设置)

-XX:+G1HeapRegionSize=n(1-32M,默认2048个分区,最大64G内存)

-XX:+G1ReservePercent=n(空闲的空间预留百分比,降低空闲空间溢出的风险,默认百分之十,基本上不用改)

-XX:+ConcGCThreads=n(GC的线程数不能超过CUP核数,超过没有意义只能使用到最多核数)

-XX:+InitiatingHeapOccupancyPercent=n(老年代大小占堆百分比达45%的时候出发mixed GC)

4、G1垃圾收集器 vs CMS垃圾收集器:

#G1不会产生碎片

#G1可以精准控制停顿,它把整堆划分为多个固定大小区域,每次根据停顿时间去手机垃圾最多的区域

5、G1垃圾收集器优化建议:

1)年轻代大小

#避免使用-Xmn 选项或者 -XX:NewRatio等其他相关选项显示设置年轻带大小

#固定年代的大小会覆盖暂停时间目标

2)暂停时间目标不要太过苛刻

#G1 GC的吞吐量目标是90%的应用程序时间和10%的垃圾回收时间

#评估G1 GC的吞吐量时,暂停时间目标不要太过苛刻,目标太过严苛表示您愿意承受更多垃圾回收开销,而这会直接影响到吞吐量

###############################

3、可视化GC日志分析工具

#GC日志输出参数:

-XX:+PrintGC 输出GC日志

-XX:+PrintGCDetails输出GC的详情日志

-XX:+PrintGCTimeStamps输出GC的时间戳(以基准时间的形式)

-XX:+PrintGCDateStamps输出GC的时间戳(以日期形式)

-XX:+PrintHeapAtGC在进行GC的前后打印出堆信息

-Xloggc:gc日志输出的路径

http://gceasy.io/ gc日志解析网站

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值