当前位置: 首页 > news >正文

【JAVA基础面经】Java中的引用类型

文章目录

  • Java中的引用类型
  • 一、强引用(Strong Reference)
  • 二、软引用(Soft Reference)
  • 三、弱引用(Weak Reference)
  • 四、虚引用(Phantom Reference)

Java中的引用类型

在 Java 中,当我们写下 Object obj = new Object(); 时,obj 是一个引用,new Object() 才是对象本体。可以把引用想象成一根绳子,对象就是绳子另一端拴着的气球。只要有绳子拉着,气球就不会飞走(不会被 GC 回收)。

Java 提供了四种不同强度的引用类型,由强到弱依次为:强引用、软引用、弱引用、虚引用。合理使用它们可以更好地管理内存,实现缓存、防止内存泄漏等场景。

一、强引用(Strong Reference)

强引用是 Java 中最常见的引用类型,也就是我们平时直接 new 出来的对象赋值。

Objectobj=newObject();// obj 是强引用

只要强引用还存在,垃圾收集器就永远不会回收掉被引用的对象。即使内存快要爆了,JVM 抛出 OutOfMemoryError 也不会去动它

Objectobj=newObject();// 强引用,气球被拉着// 即使内存紧张,这个对象也绝对安全obj=null;// 主动把绳子剪断// 现在这个对象没有强引用了,GC 可以回收

二、软引用(Soft Reference)

软引用通过 java.lang.ref.SoftReference 类实现,它比强引用弱一级。

SoftReference<MyObject>softRef=newSoftReference<>(newMyObject());

软引用就像一根弹性皮筋。当 JVM 内存充足时,垃圾收集器不会回收软引用指向的对象;但当内存不足、即将抛出 OutOfMemoryError 时,JVM 会先回收软引用指向的对象,把内存腾出来

ObjectstrongObj=newObject();SoftReference<Object>softRef=newSoftReference<>(strongObj);strongObj=null;// 切断强引用,只剩软引用System.out.println("GC前:"+softRef.get());// 大概率能获取到System.gc();// 内存充足时,GC 不会回收软引用对象System.out.println("GC后(内存充足):"+softRef.get());// 通常还在// 如果不断分配内存直到 OOM,JVM 会清理软引用
  • 使用场景:
    • 内存敏感的缓存:比如图片缓存、网页缓存。内存充足时直接从缓存拿,内存紧张时自动释放,不会导致 OOM。
    • 需要可丢弃的中间数据:比如地图应用中的瓦片数据,重建成本较高但可丢弃。

三、弱引用(Weak Reference)

弱引用是通过 java.lang.ref.WeakReference 类来创建的

WeakReference<MyObject>weakRef=newWeakReference<>(newMyObject());

弱引用就像一根头发丝。虽然也能牵着气球,但力量非常微弱。当 JVM 进行垃圾回收时,无论当前内存是否充足,都会立刻回收掉只有弱引用指向的对象

publicclassWeakReferenceDemo{publicstaticvoidmain(String[]args){// 创建一个强引用ObjectstrongObj=newObject();// 创建一个弱引用指向这个对象WeakReference<Object>weakRef=newWeakReference<>(strongObj);System.out.println("GC前,弱引用获取:"+weakRef.get());// 能拿到对象strongObj=null;// 切断强引用,现在只剩弱引用了System.gc();// 建议JVM进行垃圾回收System.out.println("GC后,弱引用获取:"+weakRef.get());// 大概率输出 null}}
  • 适用场景
    • 缓存系统:适合实现自动清理的缓存。普通缓存(如 HashMap)中,即使 Key 对应的对象已经没用了,只要缓存不清除,对象就永远不会被 GC 回收,容易造成内存泄漏。而使用弱引用作为 Key(如 JDK 提供的 WeakHashMap),当 Key 的外部强引用消失后,GC 会自动回收 Key,对应的 Value 也会从缓存中移除,不需要手动清理。
    • 对象池:用于管理对象池中的非核心对象,对象池本身用强引用持有核心对象,而用弱引用持有一些不常用、可重建的扩展对象。当内存紧张触发 GC 时,这些弱引用指向的对象会被回收,释放内存;真正需要时再重新创建。
    • 避免内存泄漏:当一个对象不应该被长期引用时,使用弱引用可以防止该对象被意外地保留,从而避免潜在的内存泄漏。例如ThreadLocalMap 的 Entry 使用弱引用指向 ThreadLocal 对象。当 ThreadLocal 外部强引用被置为 null 后,GC 会自动回收它,防止 ThreadLocal 本身泄漏。

四、虚引用(Phantom Reference)

虚引用通过 java.lang.ref.PhantomReference 类实现,它是最弱的引用类型。

ReferenceQueue<MyObject>queue=newReferenceQueue<>();PhantomReference<MyObject>phantomRef=newPhantomReference<>(newMyObject(),queue);

虚引用就像根本不存在的绳子。无论有没有虚引用,对象被 GC 回收时几乎不受影响。 虚引用必须和引用队列(ReferenceQueue)一起使用,它的 get() 方法永远返回 null

虚引用的唯一作用,就是当对象被垃圾收集器回收时,能够收到一个系统通知。JVM 会将关联的虚引用加入到引用队列中,程序可以通过监控这个队列来得知对象即将被回收,从而在回收之后做一些资源清理(如释放堆外内存)。

  • 适用场景:堆外内存管理,如 DirectByteBuffer,当 Java 堆内的对象被回收时,通过虚引用通知 JVM 去释放堆外的 native 内存
http://www.jsqmd.com/news/717599/

相关文章:

  • 避坑指南:ROS2 RealSense launch文件参数调优,解决点云稀疏、配准错位问题
  • 三菱PLC网络通信实战:C#直接通过IP连接Q系列CPU的配置与代码详解
  • DeepSeek-R1-Distill-Llama-8B部署方案:国产昇腾910B平台适配与性能调优
  • 从《黑客帝国:觉醒》Demo看UE5材质:环境光遮挡(AO)和全局位置偏移(WPO)的实战解析
  • 别再只盯着OIS了!手机拍照防抖的真相:EIS如何弥补OIS的短板?
  • 给老王家0.8元OLED屏做个‘万能’转接板:兼容Arduino/STM32的3.3V/5V电平方案
  • UE5 Water插件浮力系统深度调优:从可视化调试到动态水波控制的进阶指南
  • 用51单片机驱动你的第一个小风扇(直流电机)和旋转时钟(步进电机)
  • YOLOv5训练提速秘籍:除了换显卡,你更该优化workers和batch-size这两个‘后勤官’
  • 知识库文本清洗实战:模块化工具包的设计、实现与RAG应用集成
  • 从 IApplicationBuilder 到 ReuestDelegate:ASP.NET Core 请求管线的性能与可观测性实战
  • 什么是物料管理办法?物料管理办法包含哪些内容?
  • 30V/2A CVCC LED驱动电路设计与工业应用
  • 别再踩坑了!保姆级教程:在Ubuntu 22.04上搞定CUDA 12.1和PyTorch 2.1.0(含手动安装包下载)
  • Vector授权狗驱动安装保姆级教程(Win10/Win11兼容模式避坑指南)
  • Keil5编译报错找不到ARM编译器?手把手教你安装AC5.06(附路径配置避坑指南)
  • 从RenderDoc抓帧实战出发:拆解Unity一个Batch里到底发生了什么(glUniform4fv/glUseProgram详解)
  • 别再只用PLV了!用Python从零实现EEG相位同步指数(PSI),附完整代码与避坑指南
  • ARM架构计数器-定时器原理与虚拟化实现
  • STM32F4串口中断接收避坑指南:HAL库的HAL_UART_Receive_IT到底该怎么用?
  • 从零实现Seq2Seq机器翻译模型:LSTM架构与PyTorch实践
  • Ploopy开源耳机:基于RP2040与PCM3060的DIY音频方案
  • AirPodsDesktop:打破生态壁垒,为Windows用户重拾苹果耳机的完整灵魂
  • 别再只用3σ了!用Python的hampel库做时间序列异常检测,实战调参避坑指南
  • Qwen3-4B-Thinking-2507-Gemini-2.5-Flash-Distill效果展示:编程面试题解析全过程
  • 别再为环境变量头疼了!Win11下JDK 17与Neo4j 5.15.0一站式配置保姆级教程
  • C++深入分析讲解类的知识点
  • 深入对比:frontier_exploration vs rrt_exploration,你的扫地机器人更适合哪种算法?
  • 面向边缘安全网关高效可靠供电的MOSFET选型策略与器件适配手册
  • 深入华为FusionStorage核心:手把手拆解VBS、OSD、MDC,搞懂数据到底怎么存