java 线程引用头文件_java多线程_Java中的引用类型

本文介绍了Java中的四种引用类型:强引用、软引用、弱引用和虚引用。通过代码示例展示了它们在内存管理和垃圾回收中的不同行为。强引用是最常见的引用类型,即使在内存不足时也不会被回收。软引用在内存不足时会被回收,常用于缓存。弱引用在遇到垃圾回收时会被回收,如ThreadLocal的实现。虚引用主要用于管理堆外内存,与垃圾回收器交互。
摘要由CSDN通过智能技术生成

java中的引用分为4种,分别是:1.强引用;2.软引用;3.弱引用;4.虚引用。四种引用分别有各自的特点,下面分别通过代码对四种类型的引用进行一下测试。

1.强引用

强引用是我们平时最常用的一种引用类型。在对象被引用的时候,不会被gc的垃圾回收器回收。当没有引用时,堆中对象会被回收。

示范代码:

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 /**

2 * 验证垃圾回收机制类3 *@author

4 *5 */

6 public classM {7 //重写finalize 方法,该方法是Object对象的方法,在对象被回收时执行。8 //平时开发不建议在该位置写代码,容易导致OOM问题

9 @Override10 protected voidfinalize() {11 System.out.println("finalize");12 }13 }

验证类

1 importjava.io.IOException;2 /**

3 * 强引用 普通的引用4 *5 * 栈里的小m指向堆里的M对象,这个引用叫做强引用,只有没有任何引用指向对象的时候,对象才会被垃圾回收器回收6 *@authorLys7 *8 */

9 public classT01_NormalReference {10 public static void main(String[] args) throwsIOException {11 M m = newM();12 m=null;13 System.gc();14

15 System.in.read();16 }17 }

运行结果:

finalize//说明引用在被置为null 后,在系统gc的时候,对象被垃圾回收器回收了

2.软引用

只被软引用所引用的对象,会在jvm内存不够用的时候,被垃圾回收器回收。通过下面的测试代码我们可以看出:在m刚被定义的时候,这个时候m还是可以get到值的,然后调用系统gc,m对象也没有被垃圾回收器回收。但是当定义其他对象使内存不够用的时候,该对象就被回收掉了。该引用适用场景:一个比较大的缓存对象,经常需要读取。当系统空间足够的时候,就将其缓存在jvm中,当可用空间不足的时候,就将其回收掉。

示范代码:

1 /**

2 * 软引用3 *4 * 软应用内的对象会随着空间不够用而消失,一般应用于缓存。5 *@authorLys6 *7 */

8 public classT02SoftReference {9 public static voidmain(String[] args) {10 SoftReference m = new SoftReference<>(new byte[1024*1024*10]);11

12 System.out.println(m.get());13 System.gc();14 try{15 Thread.sleep(500);16 } catch(Exception e) {17 e.printStackTrace();18 }19 System.out.println(m.get());20 byte[] b = new byte[1024*1024*3];21 byte[] b1 = new byte[1024*1024*3];22 System.out.println(m.get());23 }24 }

代码执行参数:-Xmx20M

代码执行结果:

[B@15db9742

[B@15db9742null

//前两个打印输出证明在内存足够的情况下不会被回收,第三个输出表示,当内存不足时,软引用的对象就被垃圾回收器回收了

3.弱引用

只有弱引用引用的对象在遇到垃圾回收器执行垃圾回收的时候,就会被回收。弱引用的应用场景:ThreadLocal 对象在调用set方法,在存储对象的时候。本身将当前线程局部变量对象作为key值,存入线程的ThreadLocalMap中,被set的值作为ThreadLocalMap的value。jdk源代码如下:

static classThreadLocalMap {/*** The entries in this hash map extend WeakReference, using

* its main ref field as the key (which is always a

* ThreadLocal object). Note that null keys (i.e. entry.get()

* == null) mean that the key is no longer referenced, so the

* entry can be expunged from table. Such entries are referred to

* as "stale entries" in the code that follows.*/

static class Entry extends WeakReference>{/**The value associated with this ThreadLocal.*/Object value;

Entry(ThreadLocal>k, Object v) {super(k);

value=v;

}

}

这里的super(key)创建了一个弱引用,当ThreadLocal 对象在栈中的引用消失后,这个对象就会被垃圾回收器回收,而不必担心出现内存泄漏问题。

示范代码:

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

/*** 验证垃圾回收机制的对象

*@author**/

public classM {//重写finalize 方法,该方法是Object对象的方法,在对象被回收时执行。//平时开发不建议在该位置写代码,容易导致OOM问题

@Overrideprotected voidfinalize() {

System.out.println("finalize");

}

}

验证对象

importjava.lang.ref.WeakReference;importjava.util.WeakHashMap;/*** 弱引用 垃圾回收器看到后就回收 ,,就会被回收

* 应用场景:ThreadLocal 解决内存泄漏问题 ,但是用户自己创建的value还存在,所以tl中创建的内容,在tl不用以后,要进行remove操作。

*@authorLys

**/

public classT03_WeakRefernce {public static voidmain(String[] args) {

WeakReference m = new WeakReference(newM());

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

System.gc();

System.out.println(m.get());//ThreadLocal tl = new ThreadLocal<>();//tl.set(new M());//tl.remove();

}

}

代码执行结果:

reference.M@15db9742nullfinalize

4.虚引用

虚引用在jvm 中没有内存,用于管理在虚拟机之外的内存。如下图所示,虚引用必须当我们的虚拟机需要管理一块不存在于jvm的内存时,需要跟踪对象的垃圾回收状态,如果对象被回收了,那么将该对象的引用放入queue,根据queue中取出的对象去将对应的JVM外面的内存进行操作。

270b6b6833e8ec7f44b154e384fdb97e.png

示范代码:

1 /**

2 * 虚引用 get不到,随时被回收的对象3 *4 * 作用:管理堆外内存NIO5 *@authorLys6 *7 */

8

9 importjava.lang.ref.PhantomReference;10 importjava.lang.ref.Reference;11 importjava.lang.ref.ReferenceQueue;12 importjava.util.LinkedList;13 importjava.util.List;14

15 public classT04_phantomReference {16 private static final ReferenceQueue QUEUE = new ReferenceQueue<>();17 public static voidmain(String[] args) {18 PhantomReference phantomReference = new PhantomReference(newM(),QUEUE );19

20 new Thread(()->{21

22 try{23 System.gc();24 Thread.sleep(1000);25 } catch(Exception e) {26 e.printStackTrace();27 Thread.currentThread().interrupt();28 }29 System.out.println(phantomReference.get());30 System.gc();31

32 }).start();33

34 new Thread(()->{35 while (true) {36 Reference extends M> poll =QUEUE.poll();37 if (poll!=null) {38

39 System.out.println("----- 虚引用对象被jvm回收-------"+poll);40 }41 }42 }).start();43 }44 }

执行结果:

finalizenull

----- 虚引用对象被jvm回收-------java.lang.ref.PhantomReference@4a140fe5

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值