java垃圾回收机制_JAVA垃圾回收机制

垃圾回收机制的所有信息和资料都是来源于oracle公司对外开放的一些文档,这也是大家不管在哪里看到垃圾回收机制都差不多的原因,这些信息属于JVM公开的文档。

129343f2228f90b2f75e40ecf3c7d080.png

(一)自动垃圾收集

  • ① 介绍

自动垃圾收集是查看堆内存,识别正在使用那些对象以及那些对象未被删除以及删除未使用对象的过程。

使用中的对象或引用的对象意味着程序的某些部分仍然维护指向对象的指针。程序的任何部分都不再引用未使用的对象或未引用的对象,因此可以回收未引用对象使用的内存。

像C这样的编程语言中,分配和释放内存是一个手动过程。在java中,接触分配内存的过程由垃圾收集器自动处理。

  • ② 如何确定内存需要被回收

该过程的第一步称为标记。这是垃圾收集器识别哪些内存正在使用哪些不在使用的地方。

60b4d6105b0a751fc1611efcbfcfd558.png
  • ③ 不同类型内存的判断
    1.对象回收 - 引用计数(用到+1,用完-1)
    2.对象回收 - 可达性分析
    3.方法区回收
  • ④ 可达性分析算法

简单来说,将对象及其引用关系看作一个图,选定活动的对象作为GC Root。然后跟踪引用链条,如果一个对象和GC Roots之间不可达,也就是不存在引用,那么即可认为是可回收对象。

6cae432f82b13c986a2e83255c7b062f.png

如果一个对象没有被引用就认为可以被GC了。

可以作为GC Root的对象,通过GC Root从上到下所有的Object都找到,顺藤摸瓜。

  1. 虚拟机栈中正在引用的对象。
  2. 本地方法栈中正在引用的对象。
  3. 静态属性引用的对象。
  4. 方法区长亮引用的对象。
  • ⑤ 引用类型
  1. 强引用(StrongReference):最常见的普通对象引用,只要还有强引用指向一个对象,就不会回收(new Object())。
  2. 软引用(SoftReference):JVM认为内存不足时,才会试图回收软引用对象(缓冲场景)
  3. 弱引用(WeakReference):虽然是引用,但随时可能被回收掉。
  4. 虚引用(PhantomReference):不能通过它访问对象。供了对象被finalize以后,执行指定逻辑的机制(Cleaner)
  • ⑥ 可达性级别
  1. 强可达(Strongle Reachable):一个对象可以有一个或多个线程可以不通过各种引用访问到的情况。
  2. 软可达(Softly Reachable):就是当我们只能通过软引用才能访问到对象的状态。
  3. 弱可达(Weakly Reachable):只能通过弱引用访问时的状态。当弱引用被清除的时候,就符合销毁条件。
  4. 幻想可达(Phantom Reachable):不存在其他引用,并且finalize 过了,只能幻象引用指向这个对象。
  5. 不可达(unreachable)意味着对象可以被清除了。

(二)垃圾回收算法

1.标记-清除(Mark-Sweep)

jvm会扫描所有的对象实例,通过根搜索算法,将活跃对象进行标记,jvm再一次扫描所有对象,将未标记的对象进行清除,只有清除动作,不作任何的处理,这样导致的结果会存在很多的内存碎片。

27bc2e312d9e4dbaa12e8cc76793561d.png

2.复制(copying)算法

jvm扫描所有对象,通过根搜索算法标记被引用的对象,之后会申请新的内存空间,将标记的对象复制到新的内存空间里,存活的对象复制完,会清空原来的内存空间,将新的内存最为jvm的对象存储空间。这样虽然解决了内存内存碎片问题,但是如果对象很多,重新申请新的内存空间会很大,在内存不足的场景下,会对jvm运行造成很大的影响。

ea035e5ef69e5b1dc44b2c56fa267d1e.png

3.标记-整理(Mark-compact)

标记整理实际上是在标记清除算法上的优化,执行完标记清除全过程之后,再一次对内存进行整理,将所有存活对象统一向一端移动,这样解决了内存碎片问题。

ab106cdcb15bc68760e0e641251d23de.png

(三)分代收集

  • ① 介绍

根据对象的存活周期,将内存划分为几个区域,不同区域采用合适的垃圾收集算法。新对象会分配到Eden,如果超过 -XX:PretenureSizeThreshold:设置大对象直接进入老年代的阈值。

堆大小=新生代+老年代,新生代与老年代的比例为1:2,新生代细分为一块较大的Eden空间和两块较小的Survivor空间,分别被命名为from和to。
老年代:老年代中使用“标记-清除”或者“标记-整理”算法进行垃圾回收,回收次数相对较少,每次回收时间比较长。

1.大对象直接进入老年代

因为新生代是使用的复制算法,所以要尽量减少复制的内存,所以对象内存到一定的值后就会直接进入老年代。

2、新生代对象年龄到一定程度后进入老年代

每个对象会有一个Age的计数器,初始值为0,每经过一次GC并且存活,这个对象的Age就会加1,如果增加到一定程度(默认为15)。那么就会进入老年代中。

3、动态对象年龄判定

如果在新生代存活区中相同年龄所有对象大小的总和大于存活区的一半,年龄大于或等于该年龄的对象就会直接进入老年代。
比如现在存活区有三个对象,Age分别为2、2、3。那么Age为3的这个对象就会进入老年代。

分代这块必须理解,分代的原因,分代之后数据操作GC操作是怎么做。老年代的GC(标记,清除,整理)

(四)垃圾收集器

  • ① 串行收集器
    新生代-Serial GC -XX:+UseSerialGC

每个线程来执行所有垃圾收集工作,适合单处理器机器。

老年代 -Serial Old -XX:+UseSerialGC

可以在老年代使用,它采用标记整理算法,区别于新生代的复制算法。

串行适合物联网的,单核的,如何量大的话,会存在stop-the-world

  • ② 并行收集器
  • Parallel GC -XX:+UseParallelGC
  • Parallel Old GC -XX:+UseParallelOldGC

server 模式JVM的默认GC 选择,整体算法和Serial 比较相似,区别是新生代 和 老年代GC 都是并行进行。可以设置GC时间或吞吐量等值,可以自行进行适应性调整Eden,Survivor大小和MaxTenuringThreshold的值

也称为吞吐量优先的GC:吞吐量 = 用户代码运行时间/(用户代码运行时间 + GC 时间)

  1. -XX:ParallelGCThreads:设置用于垃圾回收的线程数。通常情况下可以和CPU数量相等,但在CPU数量较多的情况下,设置相对较小的数值也是合理的。
  2. -XX:MaxGCPauseMillis:设置最大垃圾收集停顿时间。他的值是一个大于0的整数。收集器在工作时,会调整Java堆大小或者其他参数,尽可能把停顿时间控制在MaxGCPauseMillis以内。
  3. -XX:GCTimeRatio:设置吞吐量大小。它是0-100的整数。假设GCTimeRatio的值为n,那么系统将花费不超过1/(1+n)的时间用于垃圾收集。
  4. -XX:+UseAdaptiveSizePolicy:打开自适应GC策略。在这种模式下,新生代的大小、eden和survivor的比例、晋升老年代的对象年龄等参数会被自动调整,已达到在堆大小、吞吐量和停顿时间之间的平衡点。
  • ③ 并发收集器 - XX:+UseConcMarkSweepGC 适合老年代

CMS是HotSpot在JDK1.5推出的第一款真正意义上的并发(Concurrent)收集器,第一次实现了让垃圾收集线程与用户线程(基本上)同时工作。
专用老年代,基于标记 - 清除 算法,设计目标是尽量减少停顿时间。
采用的标记-清除算法,存在着内存碎片化问题,长时间运行等情况下发生full GC,导致恶劣的停顿。
CMS会占用更多CPU资源,并和用户线程争抢。
减少了停顿时间,这一点对于互联网web等对时间敏感的系统非常重要,一直到今天,仍然有很多系统使用CMSGC

  • ④ 并行收集器 ParNew GC -XX:+UseParNewGC

新生代GC 实现,它实际是Serial GC的多线程版本。可以控制线程数量,
参数: -XX:ParallelGCThreads 最常见的应用场景是配合老娘带的CMS GC工作。
参数: -XX:+UseConcMarkSweepGC

  • ⑤ 并行收集器 -G1 -XX:+UseG1GC

G1(Garbage-First)是在JDK 7u4版本之后发布的垃圾收集器,并在jdk9中成为默认垃圾收集器。通过“-XX:+UseG1GC”启动参数即可指定使用G1 GC。从整体来说,G1也是利用多CPU来缩短stop the world时间,并且是高效的并发垃圾收集器。但是G1不再像上文所述的垃圾收集器,需要分代配合不同的垃圾收集器,因为G1中的垃圾收集区域是分区(Region)的。G1的分代收集和以上垃圾收集器不同的就是除了有年轻代的ygc,全堆扫描的fullgc外,还有包含所有年轻代以及部分老年代Region的MixedGC。

(五)垃圾回收器集合

介绍了7种垃圾回收器,有作用在新生代,也有作用在老年代的。也有G1两者都可以兼容的,G1已经基本大规模使用了。比如老年代选择CMS 可以选择新生代 Sertial 和 ParNew

7451aa9fd23b48857d1b8c994e8c5712.png

PS:不管是调优也好,先是配合对应的新老对应的垃圾收集器,如果有必要才修改垃圾收集器的参数的,垃圾回收器如何标记垃圾,如何进行垃圾收集的,收集器有哪些?它们是如何配合的。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值