Java中的垃圾回收机制

1.GC引入

(1) GC是什么?
GC (garbage collection),就是垃圾回收的意思。不管是在C中还是Java 中,都要进行垃圾回收,字C中的垃圾回收是程序员手动写代码完成回收的,可靠性更高。Java中 是JVM中的里边自己实现的一种自动回收垃圾的机制。

(2)为什么要进行垃圾回收?
在程序执行的过程中,有的变量的生命周期是很短的,这些变量可能只用一会会,用完之后,没有引用指向他们,他们就是无用的变量。要是将这些变量放在内存中,就是一种浪费。要是不把这些不用的变量、数值及时的清理掉,就会导致CPU的性能越来越低。在程序不停的调用方法时,会导致OOM 产生。

(3)什么是垃圾?
在java中,要是对象实例,没有指向他们的引用就表示这些这些变量,实例就是没用的,就是垃圾。就是要进行回收的对象。

(4)什么时候进行垃圾回收?
在创建新的对象、类加载等操作时,先要划分内存空间。要是划分的空间发现不足,就会进行GC操作,来清理内存中的无用数据,变量,让内存有更大的空间。

2.GC中的内存划分

这部分讲的是在哪些区域会存在GC操作。

(1)在JVM中的方法区里边会存在:
在 jdk 1.7中叫方法区。在 1.8中叫元空间。在GC中叫永久代虽然叫做永久代,并不是意味着,它区域里边的对象就是永久存活的,它里边的内容还是可以回收的,只不过回收效率和回收频率较低而已。在1.8 中可以理解为堆里边包含了方法区

(2)堆区
此块区域里边放的是具体对象的实例,也是进行GC的最重要的一块区域。在堆里边又将有了更详细的划分。

(3)在堆里边又将堆里边细化为: 新生代(Eden区、S0区、S1区)、老年代、永久代。给大家插入一张图描述:
在这里插入图片描述
(4)对于新生代:对用户线程影响比较小,对象的存活时间很短,被回收的概率很大,回收的效率也就越高.
(5)对于老年代:对用户线程影响比较大,对象的存活时间长,效率更低,通常是新生代的10倍左右

3.如何判断对象已经死

就是如何判断一个对象是垃圾,要是没有引用指向他就说明是垃圾,判断是引入了两个算法:引用计数算法、可达性分析算法
(1)引用计数算法:

1)含义:
新的引用指向该对象的时候,就给计数器 + 1,要是少了该对象的应用就给计数器 - 1.
2)存在问题:
要是有两个引用相互调用的时候,计数器就会不停的进行 + 1操作,造成循环。还是用一张图表示:
在这里插入图片描述

(2)可达性分析法:

就是将刚开始的一个对象记为 GC Roots ,依次往下边找,要是有对象的引用和GC roots有一个完整的链状结构,则这些连在一块的对象就是有用的。要是发现有和GC Roots之间断开的所有的对象就是无用的,就是要内进行回收的。还是用一张图来表示:
在这里插入图片描述

4.垃圾回收算法

垃圾回收算法是用来回收垃圾的一种手法,具体分为以下四种:
(1)标记清除算法:(老年代回收算法)

1)标记阶段:先要遍历每一个区域,将内存中的无用对象(垃圾)标记出来
2)清除阶段:遍历刚标记好的垃圾,进行删除。
3)存在的问题:要牵扯两次遍历,效率太低。 存在内存碎片问题。
结合上边的三点,给大家用图来表示:
在这里插入图片描述

(2)复制算法:(新生代回收算法)

1)将一个大的内存空间,划分为两个一样大的两个小的内存空间。一个里边是空白的,用来辅助。
2)将要回收的内存里边的存活对象,复制到空白的内存中
3)将原来的内存里边的所以内容进行清空。
4)缺点: 内存利用率太小
5)优点:不存在内存碎片化,性能更高。因为这是新生代的,赋值存活的效率高
6)用图来表示过程:
在这里插入图片描述

(3)标记整理算法:(老年代回收算法)

1)在标记清除的基础上,对要回收的垃圾进行整理,将他们放在一块,不在是以前的凌乱分布。
2)优点:防止了内存碎片化。
3)用图来表示:
在这里插入图片描述

(4)分代收集算法:
为了解决上边的复制算法带来的内存利用率低的问题,将内存区域进行了进一步的划分

1)将本来的内存区域划分成: 伊甸区、S0区、S1区,就是这张图:
在这里插入图片描述
2)对于新生代来说,就是复制算法的升级,对于老年代来说,还是采用标记清除法或者标记整理法来进行。
3)将内存区域划分为 伊甸区,和两块较小的幸存区(就是上边的 S1 、S2),初始三者比例是 8 : 1 : 1。
4)每次回收的时候,只有一个S区是空的,也就是回收的是伊甸区和S0区中的垃圾。
5)每一次有新的对象加入时,只给伊甸区加入。然后将剩余的两个区域的内容全部清空。
6)在下一次对象来的时候,必定有一块S区域是空的,循环前边的过程即可。
7)优点:在复制算法的基础上,将原来 50% 的空白区域编程了 10% ,提高了内存利用率.
8)用图来表示:
在这里插入图片描述

5.垃圾收集器

(1)前置概念:

1)吞吐量:用户代码运行时间 / (用户代码运行时间 + 垃圾回收运行时间 + 停顿)。举例:用户代码执行时间是 90 秒,垃圾回收用了 9 秒,还有 1 秒是其中的停顿时间,总计100 秒。此时的吞吐量就是 90% 。
2)吞吐量优先:用户线程停顿的总时间短,单个时间长也无所谓。
3)用户体验优先:单个线程停顿时间短,及时线程总的时间长也无所谓。
4)停顿时间是需要用吞吐量去换取的。吞吐量下降,会使单个线程停顿时间变短。
5)串行:执行垃圾回收线程时,用户线程停止
6)并行:执行垃圾回收线程时,用户线程和垃圾回收线程同时执行。

(2)垃圾收集器图:
相互用线连在一块的才能进行搭配使用。
在这里插入图片描述
有以下垃圾收集器:

Serial收集器

Serial收集器(新生代收集器,串行GC):用于新生代、复制算法、串行GC

ParNew收集器

ParNew收集器(新生代收集器,并行GC):用于新生代、复制算法。是 Serial 的多线程版本、能搭配 CMS 收集器让用户体验优先的应用先使用。

Parallel Scavenge 收集器

Parallel Scavenge 收集器(新生代收集器,并行GC):新生代、复制算法、搭配parallel old 让吞吐量优先

serial Old 收集器

serial Old 收集器(老年代收集器,串行GC):单线程、标记整理算法。

Parallel Old收集器

Parallel Old 收集器(老年代收集器,并行GC):标记整理算法,吞吐量优先

CMS 收集器

1)CMS 收集器(老年代收集器,并行GC):
2)用户体验优先的收集器,并发收集、低停顿
3)执行流程:
1.并发收集,低停顿
2.用的是标记 - 清除算法
3.分为 a,b,c,d4 个阶段:
a:初始标记: 先找出GC Roots 下边能关联到的所有对象,并标记出来。
b:并发标记:就是对GC Roots 进行 追踪。
c:重新标记:因为在标记的过程中,程序要是还运行的 话就会,导致有新的垃圾或者对象产生。这个阶段就是在将型产生的垃圾进行标记,时间较长。
d:并发清除:上边已经标记好了,下边进行清除。
4)缺点:用户体验优先,所以吞吐量会下降浮动垃圾问题和`内存碎片化

G1收集器

(1)叫全堆收集器,对堆上边的所有内容进行收集
(2)将堆划分成很多的 region 块,然后并行对这些块进行划分。
(3)里边还是总的分为Eden 区,S区,T区
(4)整体看是标记整理算法,局部看是复制算法。
(5)回收年轻代时用的是复制算法老年代用的是标记整理算法
(6)老年代也是四个阶段:初始标记:与CMS不同,可以进行并发执行。 并发标记:与CMS不同,先回收存活率低的对象。 最终标记: 用的是SATB算法。 筛选标记:能对存活率低的对象,进行并发的回收。

下边是对以上的垃圾收集器进行总结,以思维导图的方式整理出来:
在这里插入图片描述

6.内存分配和回收策略

(1)对象先给Eden区中放

1)就是新加入进来的对象,先给伊甸区中放。要是能放下,就直接放。
2)要是放不下,就进行minor gc。具体就是采用复制算法,对伊甸区的存活对象和其中一个S区的存活对象,进行复制,在清除两个空的区域。

(2)大的对象直接进老年代

1)将大的对象直接放在老年代中
2)但是对于生存时间很短的大对象对程序的性能影响非常大
3)因为在大对象进入老年代的时候,就需要申请连续的大空间,需要空间就可能会提前触发major gc ,速度比minor gc 慢10倍以上。

(3)将长期存活的对象直接进入老年代

1)长期存活的对象指的是在新生代里边长期存活的对象
2)判断存活:在新生代里边,要是进行一次minor gc 就给里边存活的对象的年龄 + 1。要是一个对象的年龄大于 15岁,则认为是长期存活的,这里的15 也可以自己设置,默认是15.

(4)动态对象年龄判断

要是在存活对象中,一个年龄的所有对象的大小之和 >= S / 2区域,就把这个年龄段和这个年龄段以上的所有对象放在老年代中

(5)空间分配担保

1)在进行新生代GC 的时候是从 90%的Eden区和S区(下边我们叫大区域)中,找存活对象给剩余的 10% S区里边放的。
2)要是大区域的存活对象 < S区域,则直接给里边放
3)要是 大区域存活对象 > S区域向老年代申请空间担保
4)要是老年带的空间能够放下S区放不下的对象,就表示担保成功,进行minor gc 。
5)要是老年代的区域放不下,就看他以前担保成功的几率高(信誉度高)。信誉度高,就能进行 minor gc
6)要是信誉度不够,就不能进行minor。此时会进行全堆进行gc(full gc).

下边是关于内存分配和回收策略的总结,还是以思维导图的方式呈现出来。
在这里插入图片描述

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值