Java的四种引用类型:强引用、软引用、弱引用、虚引用


前言

最近在学习ThreadLocal的时候遇到弱引用,才知道Java有四种引用类型,稍微学习了一下对几种引用类型的定义和应用做一个小小的记录。大部分是对大佬们的博客的摘录或视频截图,仅学习使用。


一、Java的四种引用类型

1、强引用

我们平常使用最多的引用,new一个对象时使用的就是强引用,只有当该对象指向null时才能被GC(垃圾回收机制)回收内存。

2、软引用

指向的对象只有在内存不足的时候才会被回收,适合用来做缓存。

3、弱引用

指向的对象遇到GC就会被回收内存,用于ThreadLocal防止内存泄漏。

4、虚引用

即使调用引用类型的get方法也获取不到对象信息,因为它一般指向的是JVM以外的内存空间。我们监听一个队列,虚引用只在其需要被垃圾回收时被告知用户添加进该队列。通俗地理解,虚引用相当于一个传话筒,通知JVM外部有一片内存需要回收了。

使用场景,JVM在内存中独立管理一片存储空间,java的垃圾回收一般只作用与JVM管理的内存,当JVM需要与外部进行网络通信时,是在外部存储空间开辟一个缓冲区,接收的数据经过缓冲区复制到JVM中,发送的数据从JVM复制到缓冲区与再发送出去。频繁的网络IO通信要不断进行数据的复制,资源大大浪费。虚引用是在JVM中创建一个对象指向外部存储空间的一片缓冲区(Direct by buffer),使得JVM能直接操作到外部的存储空间,当这片缓冲区不用时,需进行垃圾回收时,虚引用的对象会被push进监听着的队列,然后JVM就知道有一片内存需要被回收。

二、ThreadLocal

1、ThreadLocal是什么

ThreadLocalSynchonized都用于解决多线程并发访问。Synchonized是利用锁机制,进行线程间的数据共享;ThreadLocal是将线程间的数据进行隔离。

2、ThreadLocal的实现形式

ThreadLocal首先获取到当前线程,在Thread中有个ThreadLocalMap用于存储键为ThreadLocal对象,value存储用于本线程的全局静态变量,一个Thread可以new多个ThreadLocal来存放多个值,这些值在该线程中是共享的。

3、ThreadLocal内存泄漏

ThreadLocal内部的弱引用

ThreadLocal对象tl由一个弱引用对象指向,若使用强引用对象指向,则当ThreadLocal对象tl为null后,new出来的ThreadLocal对象也不会被GC回收,key的引用依然指向new出来的ThreadLocal对象,但key的值不为null,但外部无法访问到当前线程的ThreadLocalMap的new出来的ThreadLocal对象的值,map中这一条键值对相当于无法使用了,造成了内存泄漏;但即使使用弱引用对象还是会发生内存泄漏,因为当ThreadLocal对象为null时,ThreadLocal对象被GC回收,key的值变为null,也无法被访问到了。因此ThreadLoal的正确用法是,当我们确定tl对象在ThreadLocalMap中的值不用再用时,手动tl.remove()将该条目的内存释放掉。

总结

上述内容是在学习Java的四种引用类型的记录,都用一句话来概括
1)强引用是new对象时的引用,对象指向null才会被回收;
2)软引用适合做缓存,只有在内存不足时才会回收;
3)弱引用只要遇到GC就会被回收;
4)虚引用像一个传话筒,用来通知JVM它指向的内存被回收。

文章截图来自:【Java面试必学的知识点:强,软,弱,虚!马老师用一行一行代码,让你彻底学会Java引用类型!】https://www.bilibili.com/video/BV1iY4y1b7ZD?vd_source=8baf7b25ba95b215e9872bf734c622a5

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值