jvm中的引用类型

Java中的引用类型

1.强引用

一个对象A被局部变量、静态变量引用了就产生了强引用。因为局部变量、静态变量都是被GC Root对象关联上的,所以被引用的对象A,就在GC Root的引用链上了。只要这一层关系存在,对象A就不会被垃圾回收器回收。所以只要方法不退出,局部变量就会保存当前对象A的地址,该对象就不会被回收。

java 复制代码
    public static void main(String[] args) {
        ArrayList<Object> objects = new ArrayList<>();

        while (true) {
            //以下两行代码产生了两个引用关系,1.bytes变量 到 new byte[1024 * 1024]; 这个字节数组的引用关系,这也是一个强引用
            byte[] bytes = new byte[1024 * 1024];
            //2. objects集合对象 到 字节数组的关系,也是强引用
            objects.add(bytes);
            //每一轮while循环结束后,第一个引用关系就断开了。
            //但第二个引用关系没有断开!所以 bytes数组1mb大小的内存空间是不会被回收的。
            //这样就会导致每轮循环内存中增加1mb的数据,而且不能被回收
        }
    }

最后一次垃圾回收:回收前7873k,回收后7831k。回收前后内存差不多。说明有大量强引用在,而强引用不能被回收。最终内存不够用而报错。

2.软引用

由于软引用允许垃圾回收器在内存不足时回收对象。所以软引用放的对象一般都不是很重要的对象,否则内存不足时,这个对象一被回收,某些核心数据就没了。主要应用场景在缓存里面。

java 复制代码
    public static void main(String[] args) {
        ArrayList<SoftReference> objects = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            byte[] bytes = new byte[1024 * 1024];
            //软引用
            SoftReference<byte[]> softReference = new SoftReference<>(bytes);
            //将软引用对象放入集合中
            objects.add(softReference);
            System.out.println(i);
        }
        for (SoftReference softReference : objects) {//打印一下没有被回收的软引用
            System.out.println(softReference.get());
        }
    }

注:这里设置了堆内存10mb(由于还要其他强引用占用空间,所以存不下10个1mb的字节数组),且打印垃圾回收日志

说明:可以看到前七次没有进行垃圾回收,在到下标为6时,进行垃圾回收,这个时候就会把所有软引用对象全部回收,前七个对象没有了。最后再放入7-9三个字节数组对象。

最终打印集合:前七个为null(被回收了),只有后三个了。

注:这种机制很适合缓存,因为就算缓存中软引用的数据因为内存不足被回收了,也可以去数据库中查询数据。

3.弱引用

弱引用的生命周期比软引用更短,无论内存是否充足,只要垃圾回收器开始工作,弱引用关联的对象都会被回收。弱引用适用于实现可以随时被回收的缓存数据,因为它不受内存状况的影响。

java 复制代码
null
null
null
null
null
null
null
null
null
[B@4eec7777

进程已结束,退出代码0

执行结果:前九个为空,最后一个由于强引用存在,没有被回收。

4.虚引用

虚引用是最弱的一种引用关系,如果一个对象仅持有虚引用,那么它就和没有任何引用一样,它随时可能会被回收,在 JDK1.2 之后,用 PhantomReference 类来表示,通过查看这个类的源码,发现它只有一个构造函数和一个 get() 方法,而且它的 get() 方法仅仅是返回一个null,也就是说将永远无法通过虚引用来获取对象,虚引用必须要和 ReferenceQueue 引用队列一起使用。

如果一个对象只具有虚引用,那么它就和没有任何引用一样,随时会被JVM当作垃圾进行GC。

相关推荐
laplace01233 小时前
Java八股—MySQL
java·mysql·oracle
熙客4 小时前
TiDB:分布式关系型数据库
java·数据库·分布式·tidb
你想考研啊5 小时前
linux安装jdk和tomcat和并自启动
java·linux·tomcat
智驱力人工智能7 小时前
基于视觉分析的人脸联动使用手机检测系统 智能安全管理新突破 人脸与手机行为联动检测 多模态融合人脸与手机行为分析模型
算法·安全·目标检测·计算机视觉·智能手机·视觉检测·边缘计算
悟能不能悟7 小时前
java的java.sql.Date和java.util.Date的区别,应该怎么使用
java·开发语言
2301_764441337 小时前
水星热演化核幔耦合数值模拟
python·算法·数学建模
循环过三天7 小时前
3.4、Python-集合
开发语言·笔记·python·学习·算法
高山上有一只小老虎8 小时前
java 正则表达式大全
java·正则表达式
_院长大人_9 小时前
设计模式-工厂模式
java·开发语言·设计模式
凌波粒9 小时前
MyBatis完整教程IDEA版(2)--ResultMap/注解/一对多/多对一/lombok/log4j
java·intellij-idea·mybatis