Java专栏:后端不可不知的强软弱虚四种引用

Part1情景引入

在什么情况下可能发生内存泄漏?如果想清楚这个问题的来龙去脉,看源码是必不可少的,看了源码之后你发现,实际 中实际用到 ,谜底实际就是使用了弱引用 。本文主要总结概括java中强软弱虚四种引用的特点以及区别,并且进行代码验证。

Part2强引用

强引用就是我们经常用到的方式:Object o = new Object()。这非常常见, 垃圾回收时,强引用的变量是不会被回收,即使内存溢出也不会回收,只有设置 o=null,jvm 通过,发现没有 GC root 到达对象,确定为垃圾对象后,垃圾回收器才会清理堆中的对象,释放内存。当继续申请内存分配,就会OOM。

先创建一个类,重写finalize方法:

再写一个垃圾回收的测试类:

输出结果:

Part3软引用

软引用只有在内存不够的时候才会回收, 用来描述一些还有用但并非必须的对象,JDK从 1.2 开始加入了 Reference ,SoftReference 是其中一个分类,它的作用是通过 GC root 到达对象 a,如果对象仅仅有 SoftReference ,对象 a 将会在JVM OOM之前被 jvm gc 释放掉,如果这次回收还没有足够的内存,才会抛出内存溢出异常。首先设置虚拟机参数:-Xmx20M测试类:

控制台输出:

同时也可以通过 查看 jvm 堆的使用,可以看到堆在要溢出的时候就会回收掉,空闲的内存很大的时候,你主动执行 ,内存是不会回收的。

image.png

Part4弱引用

只要调用了垃圾回收(System.gc( ))就会被回收。

应用场景:只要强引用消失则应该被回收,一般用在容器里,典型应用ThreadLock,看下WeakHashMap、AQSunlock源码(Tomcat缓存用的是弱应用)

弱应用测试案例:

弱引用举例子程序

例子图示:

Part5虚引用

虚引用,主要用于堆外内存。一般是搞JVM的人用,所以基本没用。

堆外内存。NIO里面有一个Buffer,叫DirectByteBuffer(直接内存,不被jvm虚拟机管理),也叫堆外内存,被操作系统管理,如果这个引用被置为空值,则没法回收,用虚引用时,检测Queue,如果被回收了则去清理堆外内存。java可以自己回收堆外内存,用的是Unsave中的freeMemory。在此我向大家推荐一个架构学习交流圈。交流学习伪鑫:1253431195(里面有大量的面试题及答案)里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化、分布式架构等这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多

会关联一个队列,当虚引用被回收的时候回接收到关联队列里,也就是给你一个通知,被回收了,弱引用里面的值是可以get到的,虚引用根本get不到。

垃圾回收器一过来,直接就被回收了。

验证程序(先设置堆内存为20M,VM options :-Xms20M -Xmx20M,生产环境中堆空间最大最小设置成一样)

Part6关于ThreadLocal

在我们实际开发中用的还是比较多的。那它到底是个什么东东呢? 线程本地变量,我们知道 (方法内定义的变量)和 (类的属性)。

有的时候呢,我们希望一个变量的生命周期可以贯穿整个线程的一个任务运行周期(线程池中的线程可以分配执行不同的任务),在各个方法调用的时候我们可以拿到这个预先设置的变量,这就是 的作用。

比如我们想要拿到当前请求的 ,然后在当前各个方法都可以获取到, 已经帮我们封装好了, 在每个请求过来之后,都会通过 设置 ,原理就是操作 。

ThreadLocal 只是针对当前线程中的调用,跨线程调用是不行的,所以 Jdk 通过 继承 来实现。

– END –
最新BAT java经典必考面试题链接:https://pan.baidu.com/s/1B_Lc1tluda0fbdrFnexOMQ
提取码:gw8d

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值