Java 中的四种引用类型(1)

强引用是最常用的,而虚引用在业务中几乎很难用到,下面我们举例介绍一下软引用和弱引用

先来说一下软引用的回收机制。首先设置JVM参数: -Xms20m -Xmx20m , 即只有20MB的堆空间内容。在下面代码中不断地往集合中添加House对象,而每个House有2000个Door的成员变量,狭小的堆空间加上大对象的产生,就为了尽快触达内存耗尽的临界状态。

强引用

public class SoftReferenceHouse {

public static void main(String[] args) {

List houses = new ArrayList<>();

int i =0;

while (true){

try {

Thread.sleep(20);

} catch (InterruptedException e) {

e.printStackTrace();

}

houses.add(new House());

System.out.println(“i==”+(++i));

}

}

}

class House{

private static final Integer DOOR_NUMBER = 2000;

public Door[] doors = new Door[DOOR_NUMBER];

class Door{}

}

Java 中的四种引用类型

上面代码会一直执行,直到报OOM,因为强引用不会释放。

Exception in thread “main” java.lang.OutOfMemoryError: Java heap space

at com.yaspeed2.House.(SoftReferenceHouse.java:26)

at com.yaspeed2.SoftReferenceHouse.main(SoftReferenceHouse.java:17)

软引用

public class SoftReferenceHouse {

public static void main(String[] args) {

List<SoftReference> houses = new ArrayList<SoftReference>();

int i =0;

while (true){

SoftReference buyer2 = new SoftReference(new House());

houses.add(buyer2);

System.out.println(“i==”+(++i));

}

}

}

class House{

private static final Integer DOOR_NUMBER = 4000;

public Door[] doors = new Door[DOOR_NUMBER];

class Door{}

}

正常运行一段时间,内存到达耗尽的临近状态,House$Door 超过10MB左右,内存占比达到百分之七八十。

Java 中的四种引用类型

软引用的特性在数秒之后产生价值,House对象从千数量级迅速降到百数量级,内存容量迅速被释放出来。保证了程序的正常执行。

软引用SoftReference 的父类 Reference的属性: private T referent, 它指向new House()对象,而SoftReference 的get(),也是调用了super.get() 来访问父类这个私有属性。大量的House 在内存即将耗尽前,成功地一次次被清理掉。

对象buyer2虽然是引用类型,但其本身碍事占用一定内存空间的,它是被集合 ArrayList 强引用劫持的,在不断循环执行 houses.add() 后,终究会产生 OOM。

软引用、弱引用、虚引用均存在带有队列的构造方法

public SoftReference(T referent, ReferenceQueue<? super T> q) {

super(referent, q);

this.timestamp = clock;

}

可以在队列中检查哪个软引用的对象被回收了,从而把失去House 的软引用对象清理掉。

软引用一般用于在同一服务器内缓存中间结果。如果命中缓存,则提取缓存结果,否则重新计算或获取。但是,软引用肯定不是用来缓存高频数据结构的,万一服务器重启或者软引用触发大规模回收,所有的访问将直接指向数据库,导致数据库压力时大时小,甚至崩溃。

弱引用

代码如下:

public class WeakReferenceWhenIdle {

public static void main(String[] args) {

House seller = new House();

WeakReference buyer3 = new WeakReference<>(seller);

seller = null;

long start = System.nanoTime();

long count = 0;

while (true){

if(buyer3.get() == null)

{

long duration = (System.nanoTime()- start)/(1000*1000);

System.out.println("house is null and exited time = "+duration +“ms”);

break;

}else{

System.out.println(“still there.count=”+count++);

}

}

}

}

最后

金三银四到了,送上一个小福利!

image.png

image.png

专题+大厂.jpg

break;

}else{

System.out.println(“still there.count=”+count++);

}

}

}

}

最后

金三银四到了,送上一个小福利!

[外链图片转存中…(img-TSZ961A0-1714310794722)]

[外链图片转存中…(img-g0Mw60xi-1714310794723)]

[外链图片转存中…(img-eXkRDwtx-1714310794724)]

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

  • 25
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值