JVM垃圾回收器

JVM垃圾回收主要面向JVM内存区域中的Java堆以及方法区,主要是对堆进行垃圾回收

一、判断是否需要回收

引用计数法

在对象头处维护一个counter,每增加一次对该对象的引用计数器自加,如果对该对象的引用失联,则计数器自减。当counter为0时,表明该对象已经被废弃,不处于存活状态。缺点:循环引用,相当于死锁,两个变量相互引用。累积下来就会导致循环泄漏。也不可使用引用(强,软,弱,虚)。

可达性分析

又名根搜索法,枚举根节点法,使用GC root来进行垃圾回收,缺点就是在进行GC root事,所有的线程都会停止(StopTheWorld),等到所有的GC root完成时才会恢复正常运行。

GC roots:(存活对象的根
1.虚拟机栈中(栈帧中局部变量表)中引用的对象。 (JDK1.8之后虚拟机栈被称为元空间)
2.本地方法栈中引用的对象 (类似虚拟机栈)
3.方法区中静态属性引用的对象。(静态,属于整个类,类加载器存活,故该变量也分货)
4.方法区中常量引用的对象(一定存活,因为这个引用不可改变,故一定存活)

二、引用的类型

引用:OOM为OutOfMermory
1.强引用 (StrongReference)
用“=”赋值 的引用是强引用,强引用永远不会被回收,哪怕OOM。
2.软引用(SoftReference)
OOM之前会回收软引用,回收完软引用之后,内存还不够就抛出OOM。该引用内容可有可无。
使用方式:SoftReference<String> sr = new SoftReference(new String("123"));
3.弱引用(WeakReference)
只能生存到下一次即将来临的GC。
使用方式:WeakReference<String> wr = new WeakReference(new String("123"))
4.虚引用(PhantomReference)
不影响内存什么时候被回收,虚引用的目的是,在对象被回收前,收到一个系统通知。即和一个队列配合使用,判断队列中某个对象是否被回收(在被回收的一瞬间会收到系统通知)

三、垃圾回收算法

1.标记-清除算法
分为标记和清除两个阶段,首先标记处所有需要回收的对象,清除阶段进行清除。
优点:简单,高效。
缺点:效率低,清除结束后会有空间碎片太多。提前进行GC root,会导致线程停止运行。

2.复制算法
将内存分为两块(或者三块),每次只使用其中一块(或两块),需要垃圾回收时,将该块中还存活的对象复制到另外一块没用的内存块中去,再将整块内存清除干净。适合新生代
优点:简单,但不会产生空间碎片
缺点:空间浪费,每次都是用50%,内存消耗巨大,。

3.标记-整理算法
标记过后,将所有存活的对象向一端移动,然后直接清理掉边界以外的内存。适合老年代。
优点:不会产生空间碎片。
缺点:效率极低,每次移动存活对象需要时间

四、内存的分配与回收

内存分配的策略以及内存回收的时机与策略。
首先介绍三种GC,分别是Minor GC(新生代GC)、Major GC(老年代GC)、Full GC(两个代一起回收)

1.对象优先在新生代中分配

多数情况下,对象在新生代Eden区中分配。Eden SurvivorFrom SurvivorTo他们的空间比例默认为8:1:1(为了解决复制算法带来的空间浪费问题,这样只浪费了10%)通过-XX:SurvivorRatio=8来分配新生代各区的比例,设置为8,表示eden与一个survivor区的空间比例为8:1。
在这里插入图片描述

  • 第一轮:当Eden和其中一个Survivor中没有足够的内存时,进行Minor GC。将剩余的存活对象放入另外一个Survivor中。
  • 第二轮:当Eden和第一轮的最后Survivor没有足够内存的时候,进行Minor GC,将剩余的对象放入另外一个Survivor中。
  • 第N轮依次循环
  • 若还是不懂就转化为数学模型问题:将Eden园区设为1,将SurvivorFrom设为2,将SurvivorTo设为3.
    他们的第一轮就是1和2结合,内存满了之后进行GC,将存活对象放在3中,第二轮是1和3结合,内存满了之后进行GC,将存活对象放在2中,依次循环
    存放的对象大部分(80%)都是使用一到两次,假若存放的对象都是有用的,进行垃圾回收后,可用空间不足,引入一个机制,分配担保机制,拿老年代当作担保,放入老年代。(第5点)
2.大对象直接进入老年代

需要大量连续内存空间的Java对象,直接进入老年代。假如占用大部分的Eden园区回来复制,浪费资源。
判断依据:-XX:PretenureSizeThreshold=10M 则超过10M即为大对象直接进入老年区。

3.长期存活的对象进入老年代

新生代中的对象,在进入Survivor区(复制算法中的)后,会有年龄,每通过一次GC,年龄+1,在达到阈值(默认15)后会进入老年代。

4.动态对象年龄判定

如果Survivor空间中相同年龄对象大小总和大于Survivor空间的一半,年龄大于等于该年龄的对象可以直接进入老年代(超过峰值的一半放入老年代)。(品,你细细品)

5、空间分配担保机制

在Minor GC之前,虚拟机会检查,只要老年代的剩余最大连续空间大于新生代对象总大小或者历次晋升对象的平均大小就会进行Minor GC,否则进行Full GC.可以避免Full GC过于频繁.(提前预防)

6、老年代GC

使用标记-整理算法,因为不会产生空间碎片,而且不怕回收时间久,在Major GC之后的内存对象回收后释放的可用空间较少。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值