【JVM】JVM03(图解垃圾回收机制)上

  • 🍅文章发布日期:2021.12.29
  • 👋java学习之路!
  • 欢迎各位🔎点赞👍评论收藏⭐️
  • 🎄新年快乐朋友们🎄
  • 👋jvm学习之路!

文章笔记参考黑马程序员

文章目录

  • ⭐️1.如何判断对象可以回收

  • ⭐️1.1引用计数法

  • ⭐️1.2可达性分析算法

  • ⭐️2.五种引用

  • ⭐️2.1强引用

  • ⭐️2.2 软引用

  • ⭐️2.3 弱引用

  • ⭐️引用队列

  • ⭐️2.4虚引用

  • ⭐️2.5终结器引用

  • ⭐️2.6引用总结

  • ⭐️3.垃圾回收算法

  • ⭐️3.1标记清除

  • ⭐️3.2标记整理

  • ⭐️3.3复制

  • ⭐️4分代垃圾回收

  • 大对象处理策略

  • ⭐️4.1分代垃圾回收总结


在这里插入图片描述

⭐️1.如何判断对象可以回收

============================================================================

⭐️1.1引用计数法

========================================================================

一个对象收到引用时计数+1,一个对象失去引用时计数-1,一个对象的引用计数为0时,该对象被当作垃圾进行回收

但是这样会有一个问题

循环引用

在这里插入图片描述

当A对象和B对象相互引用时,他们的引用计数都是1,但是他们却没有被其他对象所使用,这样因为他们的引用计数不能归0导致两个对象不能作为垃圾被回收,导致内存泄漏

⭐️1.2可达性分析算法

==========================================================================

此算法为java虚拟机采用的一种垃圾回收算法,首先要确定一个肯定不会被当成垃圾回收的对象GC Root(根对象)

  • java虚拟机中的垃圾回收器采用可达性分析来探索所有存活的对象

  • 扫描堆中的对象,看是否能够沿着GC Root对象为起点的引用链找到该对象,找不到,表示可以回收

可以作为GC Root的对象

  • 虚拟机栈(栈帧中的本地变量表)中引用的对象

  • 方法区中类静态变量引用的对象

  • 方法区中常量引用的对象

  • 本地方法栈中JNI(即一般说的Native方法)引用的对象

⭐️2.五种引用

======================================================================

  1. 强引用

  2. 软引用

  3. 弱引用

  4. 虚引用

  5. 终结器引用

下面我们分别进行描述

⭐️2.1强引用

======================================================================

在这里插入图片描述

我们平时所使用的引用便是强引用,比如我们new一个对象A,把这个对象通过等号(赋值运算符)赋值给一个变量m,那么就称这个变量m强引用了刚刚的对象A

强引用的特点:

只要沿着GC root的引用链能够找到该对象,他就不会被垃圾回收,就比如上图中的C对象能找到A1对象,那么A1对象就不能被回收,当B对象和C对象对A1对象的引用都断开时,A1对象才能被垃圾回收

⭐️2.2 软引用

=======================================================================

在这里插入图片描述

如图,A2对象使用过软引用对象被C对象间接引用到,只要满足垃圾回收时,并且回收完内存也不够时,那么软引用所引用的A2对象就会被释放掉

所以软引用引用对象被释放的条件是

  • 没有强引用对象引用它

  • 发生垃圾回收

  • 垃圾回收之后内存不够

软引用的应用案例

public static void soft(){

ArrayList<SoftReference<byte[]>> list = new ArrayList<>();

for (int i = 0; i < 5; i++) {

SoftReference<byte[]> ref = new SoftReference<>(new byte[_4MB]);

System.out.println(ref.get());

list.add(ref);

System.out.println(list.size());

}

System.out.println(“循环结束:”+list.size());

for (SoftReference<byte[]> ref : list) {

System.out.println(ref.get());

}

}

list先引用软引用对象,软引用对象间接的引用byte数组

list和SoftReference之间是强引用,SoftReference和byte数组之间是软引用

内存充足的时候软引用引用的对象保留,但是当内存不足的时候,软引用引用的对象就会被清除

⭐️2.3 弱引用

=======================================================================

在这里插入图片描述

和软引用的区别是,当弱引用引用该对象时,发生垃圾回收不管内存是否充足,弱引用所引用的对象都会被回收

public class Demo03 {

private static final int _4MB = 410241024;

public static void main(String[] args) throws IOException {

List<WeakReference<byte[]>> list = new ArrayList<>();

for (int i = 0; i < 10; i++) {

//关联了软引用对象和引用队列,当软引用所关联的byte[]被回收时,软引用自己会加入到引用队列queue中去

WeakReference<byte[]> ref = new WeakReference<>(new byte[_4MB]);

list.add(ref);

for (WeakReference<byte[]> w: list){

System.out.println(w.get()+“”);

}

System.out.println();

}

System.out.println(“循环结束:”+list.size());

}

}

通过list集合引用WeakReference,通过WeakReference间接的引用byte[]数组,这样进行垃圾回收,就会尝试把WeakReference运用的byte数组所占用的内存做释放

⭐️引用队列

====================================================================

在这里插入图片描述

当软引用所引用的对象或弱引用引用的对象被清除之后,软引用和弱引用本身并不会消失,软引用和弱引用本身也是一个对象,此时软引用和弱引用会进入引用队列

软引用和弱引用自身也要占用一定内存,如果想释放软引用和弱引用的内存,需要使用引用队列找到它们,对其做进一步的处理

引用队列操作代码

public class Demo02 {

private static final int _4MB = 410241024;

public static void main(String[] args) throws IOException {

ArrayList<SoftReference<byte[]>> list = new ArrayList<>();

//引用队列

ReferenceQueue<byte[]> queue = new ReferenceQueue<>();

for (int i = 0; i < 5; i++) {

//关联了软引用对象和引用队列,当软引用所关联的byte[]被回收时,软引用自己会加入到引用队列queue中去

SoftReference<byte[]> ref = new SoftReference<>(new byte[_4MB],queue);

System.out.println(ref.get());

list.add(ref);

System.out.println(list.size());

}

Reference<? extends byte[]> poll = queue.poll();

while (poll != null){

list.remove(poll);

poll = queue.poll();

}

for (SoftReference<byte[]> ref : list) {

System.out.println(ref.get());

}

}

}

关联软引用对象和引用队列,当软引用所关联的byte[]被回收时,软引用自己会加入到引用队列queue中去,之后查看引用队列中是否有软引用,有就将其移出

⭐️2.4虚引用

======================================================================

在这里插入图片描述

ByteBuffer被回收的时候,他分配的直接内存并不能被java的垃圾回收管理,所以我们将虚引用对象Cleaner进入引用队列,虚引用所在队列会有一个叫RefrenceHandlel的线程,来定时到这个引用队列中找新入队的Cleaner,如果有就调用Cleaner中的clean方法,根据记录的直接内存的地址调用Unsafe.freeMemary方法来清理直接内存

在这里插入图片描述

⭐️2.5终结器引用

========================================================================

在这里插入图片描述

所有的java对象都继承自Object类,Object类有finallize()终结方法,当对象重写了终结方法并且没有强引用,他就可以被当成垃圾回收,终结方法的调用依靠终结器引用

在这里插入图片描述

如上图当A4对象被垃圾回收时,在A4对象被真正清除之前,终结期引用进入引用队列,再由一个优先级很低的线程(finallizeHandler)查看引用队列中的终结器引用,通过终结器引用找到将要垃圾回收的对象,调用对象的finallize方法,调用之后,该对象就可以被垃圾回收了

⭐️2.6引用总结

=======================================================================

在这里插入图片描述

⭐️3.垃圾回收算法

========================================================================

⭐️3.1标记清除

=======================================================================

在这里插入图片描述

第一个阶段:标记

顺着GC Root查找没有引用的对象,将其进行标记

在这里插入图片描述

第二个阶段:清除

将垃圾对象所占用的空间释放

在这里插入图片描述

释放不意味着将每一个字节进行清理操作,清除只是把对象所占用内存的起始与结束地址记录下来,放在一个较空闲的地址链表里,下次分配内存的时候会直接覆盖这部分内存

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

最后

2020年在匆匆忙忙慌慌乱乱中就这么度过了,我们迎来了新一年,互联网的发展如此之快,技术日新月异,更新迭代成为了这个时代的代名词,坚持下来的技术体系会越来越健壮,JVM作为如今是跳槽大厂必备的技能,如果你还没掌握,更别提之后更新的新技术了。

更多JVM面试整理:

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
以扫码获取!!(备注Java获取)**

img

最后

2020年在匆匆忙忙慌慌乱乱中就这么度过了,我们迎来了新一年,互联网的发展如此之快,技术日新月异,更新迭代成为了这个时代的代名词,坚持下来的技术体系会越来越健壮,JVM作为如今是跳槽大厂必备的技能,如果你还没掌握,更别提之后更新的新技术了。

[外链图片转存中…(img-Xp7u8SZI-1713529100829)]

更多JVM面试整理:

[外链图片转存中…(img-DZN4Lpf4-1713529100832)]

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值