对GC机制的理解

前言

java程序员只需要关注业务流程无需管理内存,JVM会自动帮我们管理。程序运行过程中,对象、类信息等不停增加,占据的内存会越来越多,不及时清除可能是系统变慢甚至系统崩溃。因此java提供GC(Garbage Collection)机制自动地清除“垃圾对象”,回收空余空间。正因为GC机制由JVM管理,java程序员无法控制它的运行,GC时间也无法控制。 因此需要了解它,在工作中注意这方面。

垃圾对象检测(清除哪些对象)

  1. 引用计数法   堆内对象会有引用数,堆内对象被引用时引用数加一,不被引用了引用数减一,,引用数为0的认为可以回收,,  优点是实现简单判定简单, 但是会频繁对计数器加减,而且无法处理相互引用问题。
  2. 可达性分析(根搜索算法)   将一系列对象组为“Gc Roots”,从Gc Roots的引用、引用的引用,这样下去组成一个引用链,不在这个链中的认为是可回收对象。 GC Roots包括方法区中静态变量引用的对象、常量引用的对象, 栈和本地方法栈中的引用对象,,静态变量和常量自然是需要存储不能回收的,,栈和本地方法栈中的引用,保存着线程运行的记录,和本线程的生命周期一致,线程结束了,引用才会回收。 因此GC Roots是此时“有用”的对象集合,GC Roots对象引用的对象自然也是有用的,也不能回收,,跟引用链没有关系的,即使互相引用,也认为是垃圾对象。 

垃圾清除算法(怎么清除)

  1. 标记清除法  分为标记和清除阶段,标记阶段区分出存活对象和应该回收对象,清除阶段清除回收对象。  实现逻辑比较简单,是最基础的算法;不过标记和清除效率都不高,而且清除后内存并没有整理,可能出现垃圾碎片影响大对象的内存分配,导致full-gc提前。
  2. 复制算法  将空间分成同样大小两块,一时间只使用一块。发生垃圾清除时,将正在使用这块的存活对象复制到另外一块,然后清除原先块。下次清除时执行同样的复制操作,反复切换使用的内存块。  这种方法只需要复制存活对象,效率是比较高的,整块清除解决了内存碎片问题;不过同一时间内只使用一块,浪费一半的内存,存活率高的区域复制开销会很大。 用于对象存活率低的区域效率会比较高,因为复制开销很小, JAVA新生代就适合使用复制算法
  3. 标记压缩法(标记整理法)  是标记清除法的改进版,标记阶段后,将存活对象的位置移动到一块连续空间,记录空间的起始位置,然后清除这段空间之外的内存。 这样清除完的空间不会出现碎片。 JAVA老年代适合标记压缩算法
  4. 分代回收   新生代中GC频繁,对象存活率低,使用复制算法提高GC效率,将survivor区域分为等大的两块,只使用一块存储存活对象。发生GC时,将eden区和使用中的survivor区内的存活对象复制进空的一块survivor,空survivor内存不够时借用老年代暂时存储。然后清除eden区和原survivor块。   老年代中对象存活率高,不会频繁GC,使用标记压缩法可以压缩内存空间,减少内存碎片,提高内存利用率

垃圾回收器

具体的回收实现

  1. Serial GC(串行回收器) 单线程的回收机制,新生代复制算法,老年代标记压缩。回收时会暂停其它线程,造成应用暂停。适用于没有多线程需求、对响应时间要求不大的应用。 通过-XX:+UseSerialGC 启用,是client模式的默认收集器。
  2. ParNewGC 新生代并行使用复制算法,老年代串行使用标记压缩算法,,提高了新生代的GC效率,可以与CMS配合并用在server端。 -XX:+UseParNewGC 启用
  3. Parallel Scavenge GC   新生代并行使用复制算法,老年代并行标记压缩算法,,适用于多CPU,要求暂停时间很短的应用,是server模式的默认垃圾收集器。 -XX:+UseParallelGC 启用   -XX:ParallelGCThreads=4指定线程数
  4. Parallel Old   是Parallel收集器的老年代版本,老年代多线程使用标记压缩算法。 -XX:+UseParrallelOldGC
  5. CMS(Concurrent Mark Sweep) 并发标记清除  追求最短的回收时间,高并发、响应快,基于“标记清除法”。B/S架构的系统中为了更快的响应速度更好的用户体验,常常使用CMS收集器。 CMS收集器的工作过程分为初始标记、并发标记、重新标记、并发清除四个阶段。初始标记阶段,标记GC Roots直接关联对象,很快,会暂时停止应用;并发标记阶段,进行根搜索算法,判断对象是否存活,耗时长,可以与应用一起执行;重新标记阶段,修正并发标记期间发生变动的对象标记记录,会暂停应用,以免出现新的变动,比较块;并发清除阶段,清除不存活对象,可以与应用一起执行。 因为并发标记、并发清除阶段用时最长,而且可以与应用一起执行,因此总体上是并发执行的。  优点:并发收集,响应快  缺点:标记清除算法带来的内存碎片问题;并发阶段会占用CPU,影响应用的运行速度。   -XX:+UseConcMarkSweepGC  启用CMS收集器  -XX:ParallelCMSThreads 设置CMS线程数量  -XX:+CMSFullGCsBeforeCompaction 设置进行几次GC后,对内存进行压缩,处理内存碎片, 也可以 -XX:+ UseCMSCompactAtFullCollection,GC一次整理一次。
  6. Garbage-First(G1) 也关注快速响应、适用于堆内存大的应用的垃圾收集。-XX:+UseG1GC 启用G1收集器。 局部采用复制算法,整体采用标记压缩算法,不会产生内存碎片。

垃圾收集器选用

  1. 单CPU机器小内存、没有多线程要求的,使用SerialGC即可
  2. 多CPU机器,要大吞吐量的应用 ,使用Parallel Scavenge GC
  3. 多CPU机器,要求快速响应的,使用CMS 或者 G1, 堆内存大的使用G1会更快。

查看程序的运行状态

  1. jmap、jstack工具
  2. JVisualVM

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值