java 中的引用类型

1、强引用类型

2、弱引用

3、软引用

我们来举例说明下

复制代码
package www.weiyuan.test;

import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;

public class Test {

    public static void main(String[] args) {
        // TODO Auto-generated method stub

//创建了一个强引用类型 String str = "abc"; //创建一个软引用对象 SoftReference<String> sfr = new SoftReference<String>(str); //创建一个弱引用类型 WeakReference<String> wrf = new WeakReference<String>(str); } }
复制代码

对象的可及性:一个对象可由多个变量来来引用,对象的可及性由最强引用类型来决定

 上面对象adc有三个引用,一个是强可及,一个是软可及,还有一个是弱可及,最强引用是强可及

强可及对象永远不会被gcc垃圾回收器回收

软可及对象当系统内存不足的时候,gcc会把软可及对象回收掉

弱可及对象当gcc发现这个对象是弱可及对象就马上将对象回收

复制代码
package www.weiyuan.test;

import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;

public class Test {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
         String str = "abc";
       //创建一个软引用对象
         SoftReference<String> sfr = new SoftReference<String>(str);
         //创建一个弱引用类型
         WeakReference<String> wrf = new WeakReference<String>(str);
         //去除强可及str对象不再和adc对象存在任何关系
         str = null;
         //通过软可及获得对象的值
         String result1 = sfr.get();
         //通过弱可及获得对象的值
         String result2 = wrf.get();
         System.out.println("result1 ="+result1);
         System.out.println("result2 ="+result1);
    }

}
复制代码

 

输出的结果是:

result1 =abc
result2 =abc

str = null;就是去掉str和对象"abc"的强可及关系,此时依然可以通过软引用和弱引用获得对象所关联的值

弱可及对象当gcc发现这个对象是弱可及对象就马上将对象回收

复制代码
package www.weiyuan.test;

import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;

public class Test {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
         String str = "abc";
       //创建一个软引用对象
         SoftReference<String> sfr = new SoftReference<String>(str);
         //创建一个弱引用类型
         WeakReference<String> wrf = new WeakReference<String>(str);
         //去除强可及str对象不再和adc对象存在任何关系
         str = null;
         //清除软引用的引用链
         sfr.clear();
         //通过弱可及获得对象的值
         String result2 = wrf.get();
         //通过软可及获得对象的值
         String result1 = sfr.get();
        
         System.out.println("result1 ="+result1);
         System.out.println("result2 ="+result2);
    }

}
复制代码

 

我们使用

        sfr.clear();去掉对象的软引用链接,这个时候对象的可及性是弱引用对象,清除之后通过软引用我们无法获得对象的值,但是依然可以通过弱引用获得对象的值,我们来看日志的打印输出

result1 =null
result2 =abc

在上面代码的基础上,我们知道当前对象的可及性是弱引用,我们收到调用gcc回收,看能否在获得对象的值

复制代码
package www.weiyuan.test;

import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;

public class Test {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
         String str = "abc";
       //创建一个软引用对象
         SoftReference<String> sfr = new SoftReference<String>(str);
         //创建一个弱引用类型
         WeakReference<String> wrf = new WeakReference<String>(str);
         //去除强可及str对象不再和adc对象存在任何关系
         str = null;
         //清除软引用的引用链
         sfr.clear();
         //运行垃圾回收器
         System.gc();
         //通过弱可及获得对象的值
         String result2 = wrf.get();
         //通过软可及获得对象的值
         String result1 = sfr.get();
        
         System.out.println("result1 ="+result1);
         System.out.println("result2 ="+result2);
    }

}
复制代码

 

该对象已经是弱引用了,我们调用了系统的垃圾回收器,发现对象如果是弱引用,就立刻回收该对象的值

我们来看看日志的打印

result1 =null
result2 =abc

居然在垃圾回收器之后,居然还可以通过弱引用获得对象的值

这是为啥了,这里因为埋了一个坑

因为创建的对象

 "abc"是存在在系统的常量池中的,我们使用gc是无法回收常量池中的对象的,gc只能回收堆内存中的弱引用对象
我们把
复制代码
package www.weiyuan.test;

import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;

public class Test {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
         String str = new String("abc");
       //创建一个软引用对象
         SoftReference<String> sfr = new SoftReference<String>(str);
         //创建一个弱引用类型
         WeakReference<String> wrf = new WeakReference<String>(str);
         //去除强可及str对象不再和adc对象存在任何关系
         str = null;
         //清除软引用的引用链
         sfr.clear();
         //运行垃圾回收器
         System.gc();
         //通过弱可及获得对象的值
         String result2 = wrf.get();
         //通过软可及获得对象的值
         String result1 = sfr.get();
        
         System.out.println("result1 ="+result1);
         System.out.println("result2 ="+result2);
    }

}
复制代码

 

我们运行下代码:

result1 =null
result2 =null

通过new String的对象都是存在在堆内存中,所以我们使用gc就能够回收了。

 



posted on   luzhouxiaoshuai  阅读(201)  评论(0编辑  收藏  举报

编辑推荐:
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

点击右上角即可分享
微信分享提示