首页 > 编程语言 >Java-引用类型

Java-引用类型

时间:2023-12-08 11:13:20浏览次数:30  
标签:obj Object 回收 Java 引用 类型 new 内存

Java-引用类型

四种引用类型(强引用、软引用、弱引用、虚引用)在Java中具有不同的使用场景,可以根据程序的需求和内存管理的要求来选择适当的引用类型。

1. 强引用(Strong Reference):

使用场景:

  • 在绝大多数情况下,我们使用的都是强引用。
  • 当一个对象具有强引用时,垃圾回收器不会回收该对象,即使内存不足时,也不会回收具有强引用的对象。

示例:

Object obj = new Object(); // 强引用

2. 软引用(Soft Reference):

使用场景:

  • 适用于对内存敏感的缓存场景,当内存不足时,可以回收软引用关联的对象,以释放内存。
  • 常用于缓存中,当内存紧张时,垃圾回收器会尽量保留软引用关联的对象,但不保证绝对保留。

示例:

import java.lang.ref.SoftReference;

Object obj = new Object();
SoftReference<Object> softRef = new SoftReference<>(obj);
obj = null; // 取消强引用

3. 弱引用(Weak Reference):

使用场景:

  • 适用于临时性对象的缓存,例如缓存中的对象可以很快被重新计算或重建。
  • 主要用于避免内存泄漏,当对象不再被强引用时,会被垃圾回收器快速回收。

示例:

import java.lang.ref.WeakReference;

Object obj = new Object();
WeakReference<Object> weakRef = new WeakReference<>(obj);
obj = null; // 取消强引用

4. 虚引用(Phantom Reference):

使用场景:

  • 主要用于对象被垃圾回收时收到通知或执行某些清理操作的场景。
  • 通常与引用队列(ReferenceQueue)一起使用,当虚引用关联的对象被垃圾回收时,虚引用会被放入引用队列中,可以在队列中获取通知。

示例:

import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;

Object obj = new Object();
ReferenceQueue<Object> referenceQueue = new ReferenceQueue<>();
PhantomReference<Object> phantomRef = new PhantomReference<>(obj, referenceQueue);
obj = null; // 取消强引用


//下面是一个简单的示例,演示了如何使用 PhantomReference 和 ReferenceQueue 来实现在对象被垃圾回收时收到通知:

import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;

class MyObject {
    // 一些对象的状态和行为
}

public class ObjectCleanupExample {

    public static void main(String[] args) {
        MyObject myObject = new MyObject();
        ReferenceQueue<MyObject> referenceQueue = new ReferenceQueue<>();
        PhantomReference<MyObject> phantomReference = new PhantomReference<>(myObject, referenceQueue);

        // 此时 myObject 还有强引用
        myObject = null;

        // 在某个时刻,垃圾回收器会回收 myObject 对象,并将 phantomReference 放入 referenceQueue
        System.gc(); // 这里只是建议垃圾回收,不能保证立即执行
        try {
            // 等待垃圾回收器通知,remove会让当前线程阻塞,直到其中一个对象可用或给定的超时期到期
            PhantomReference<MyObject> clearedRef = (PhantomReference<MyObject>) referenceQueue.remove();
            System.out.println("Object has been garbage collected: " + clearedRef.get());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

总体来说,选择引用类型应该根据具体的需求和对内存管理的要求。强引用适用于绝大多数场景,而软引用、弱引用、虚引用则可以用于一些特定的场景,如缓存、内存敏感的情况或者需要在对象被回收时执行特定操作的情况。

小问题:ThreadLocalMap.Entry为什么使用弱引用,而不是软引用?

ThreadLocalMap​中使用弱引用(WeakReference​)而不是软引用(SoftReference​)的主要原因是避免潜在的内存泄漏问题。

ThreadLocalMap​ 是 ThreadLocal​ 的内部实现,它通过使用弱引用来关联键(ThreadLocal​对象)和值,确保在线程的生命周期结束后,对应的键值对可以被垃圾回收。

如果使用软引用,由于软引用的特性是在内存不足时才会被回收,可能导致即使线程结束,ThreadLocal​ 对象仍然被保留,对应的值也不会被及时释放。这样可能导致内存泄漏,因为线程已经结束,但相关的资源无法被释放。

弱引用相比软引用更加“弱”,只要没有强引用指向 ThreadLocal​ 对象,就有可能被垃圾回收。这确保了在不再需要时能够及时释放与 ThreadLocal​ 相关的资源,从而避免了潜在的内存泄漏问题。

总体而言,选择弱引用而不是软引用是为了保证对应资源在合适的时机能够被及时回收,以防止内存泄漏。这是ThreadLocalMap​在设计上的权衡考虑。

标签:obj,Object,回收,Java,引用,类型,new,内存
From: https://www.cnblogs.com/anhaoyang/p/javareference-type-15dbqb.html

相关文章

  • java JSON对象与字符串间的转换
    importcom.alibaba.fastjson.JSON;importcom.alibaba.fastjson.JSONObject;//字符串转为JSON对象StringstrParam="{\"callerid\":\"013941128270\",\"timestart\":\"2021-07-2709:37:42\",\"status\"......
  • Java运算符
    1.运算符1.1算术运算符算术运算符是对数值型的变量进行运算publicclassOperator{publicstaticvoidmain(Stringargs[]){System.out.println(10/4);//2System.out.println(10.0/4);//2.5doubled=10/4;System.out.println(......
  • java 正则表达式 用法
    在一个复杂的字符串中,使用正则表达式来取其中某个值importjava.util.regex.*;//正则表达式引用//复杂的字符串Stringinput="{\"pbxToken\":\"1ja930jsdlij912h94hk5l35poeweer\"}"+"{\"LS_CallStatus_Event_Type\":\"\",\"callId......
  • JavaWeb - Day03 - Ajax、前端工程化、Element
    01.Ajax-介绍Ajax概念:AsynchronousJavaScriptAndXML,异步的JavaScript和XML。作用:数据交换:通过Ajax可以给服务器发送请求,并获取服务器响应的数据。异步交互:可以在不重新加载整个页面的情况下,与服务器交换数据并更新部分网页的技术,如:搜索联想、用户名是否可用的校验等等......
  • Java第五课_函数重载递归和初识数组
    1.函数重载//关键字:public,static等//保留字:关键字的预备役var,goto//jdk11开始,还有JS里var升级为关键字:var变量名=初始值;//重载/overload:在同一个类中,允许函数重名,但是他们的参数列表必须不同.......
  • 前端学习-JavaScript学习-js基础-API02
    学习视频:黑马程序员视频链接事件监听三要素:事件源、事件类型、事件处理程序随机点名案例<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width,initial-scale=1.0"&......
  • Java 读取EXCEL表格中的数据,将数据转为SQL语句
    **[参考文档](https://blog.csdn.net/wl_Honest/article/details/83985751?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_utm_term~default-0-83985751-blog-81103171.pc_relevant_paycolumn_v3&spm=1001.2101.3001.4242.1&utm_relevant_index=3)......
  • Java登陆第二十天——HTML常用标签
    文本标签文本常用的HTML标签:标签名标签描述<h1></h1>标题标签<h6></h6>标题标签<p></p>段落标签<hr>换行标签<br>换行标签标签栗子:<!DOCTYPEhtml><htmllang="en"><head><metacharset=&quo......
  • “数组”类型(python中都可[]的一些数据类型)
    “数组”类型(python中都可[]的一些数据类型)list特点是可变的、能动态扩容,可存储Python中的一切对象,使用时不用指定存储的元素的类型。>>>arr=["one","two","three"]>>>arr[0]'one'#动态扩容>>>arr.append(4)>>>arr['one',......
  • 关键字 开发-10 封装引用自定义函数变量
    前言前面在yaml文件中引用内置函数以及自定义函数和变量时,都是在每个关键字后面进行单独得渲染,为了方便引用,于是我们单独对这块的内容进行封装。1.新增自定义函数和变量在utils下新建自定义函数和变量的文件,my_builtins.py,新增了在接口中需要用到的一些变量和函数。这样,在传......