• java强应用,软引用,弱引用,虚引用的区别


    各个引用的区别

    强引用: 强引用指的是通过new对象创建的引用,垃圾回收器即使是内存不足也不会回收强引用指向的对象。

    软引用: 软引用是通过SoftRefrence实现的,它的生命周期比强引用短,在内存不足,抛出OOM之前,垃圾回收器会回收软引用引用的对象。软引用常见的使用场景是存储一些内存敏感的缓存,只有当内存不足时会被回收。

    弱引用: 弱引用是通过WeakRefrence实现的,它的生命周期比软引用还短,GC只要扫描到弱引用的对象就会回收。弱引用常见的使用场景也是存储一些内存敏感的缓存。

    虚引用: 虚引用是通过PhantomRefrence实现的,它的生命周期最短,随时可能被回收。如果一个对象只被虚引用引用,我们无法通过虚引用来访问这个对象的任何属性和方法。get()返回的都是null,它的作用仅仅是保证对象在finalize后,做某些事情。虚引用常见的使用场景是跟踪对象被垃圾回收的活动,当一个虚引用关联的对象被垃圾回收器回收之前会收到一条系统通知。

    实验来验证:

    1. package com.figo.test;
    2. import lombok.Getter;
    3. import lombok.Setter;
    4. import org.junit.jupiter.api.Test;
    5. import java.lang.ref.PhantomReference;
    6. import java.lang.ref.ReferenceQueue;
    7. import java.lang.ref.WeakReference;
    8. import java.util.LinkedList;
    9. import java.util.List;
    10. /**
    11. * @ClassName:ReferenceTest
    12. * @PackageName:com.figo.test
    13. * @Description:类描述
    14. * @Date:2022/7/20 10:49
    15. * @Author:figo
    16. */
    17. public class ReferenceTest {
    18. private ReferenceQueuesuper Employee> referenceQueue;
    19. public class Employee
    20. {
    21. @Getter
    22. @Setter
    23. String name="andy";
    24. @Getter
    25. @Setter
    26. int age=100;
    27. }
    28. @Test
    29. public void testReference(){
    30. //new出来是强引用
    31. Employee employee = new Employee();//调用无参构造函数,自动为相关属性赋值
    32. //软引用,在内存没有出现oom时不会被回收,不能和WeakReference一起使用,否则WeakReference失效
    33. //SoftReference employeeSoftReference = new SoftReference<>(employee);
    34. //弱引用
    35. WeakReference employeeWeakReference=new WeakReference<>(employee);
    36. //虚引用
    37. referenceQueue=new ReferenceQueue<>();
    38. PhantomReference employeePhantomReference=new PhantomReference<>(employee, referenceQueue);
    39. System.out.println("------Before Gc------");
    40. //System.out.println("软引用对象是否还在="+employeeSoftReference.get());
    41. System.out.println("弱引用对象是否还在="+employeeWeakReference.get());
    42. System.out.println("虚引用对象是否还在="+employeePhantomReference.get());
    43. employee=null;//被引用对象清空
    44. System.gc();//进行垃圾回收, 底部实现Runtime.getRuntime().gc();
    45. System.out.println("------After Gc------");
    46. //System.out.println("软引用对象是否还在="+employeeSoftReference.get());
    47. System.out.println("弱引用对象是否还在="+employeeWeakReference.get());
    48. System.out.println("虚引用对象是否还在="+employeePhantomReference.get());
    49. //向堆中填充数据模拟OOM
    50. List list = new LinkedList<>();
    51. try{
    52. for (int i = 0; i < 10000; i++) {
    53. //System.out.println("SoftReference == "+employeeSoftReference.get());
    54. list.add(new Byte[1*1024*1024]);
    55. }
    56. }catch (Throwable e){
    57. System.out.println("------After OOM------");
    58. //System.out.println("软引用对象是否还在="+employeeSoftReference.get());
    59. System.out.println("弱引用对象是否还在="+employeeWeakReference.get());
    60. System.out.println("虚引用对象是否还在="+employeePhantomReference.get());
    61. e.printStackTrace();
    62. }
    63. }
    64. }

    输出结果:

    ------Before Gc------
    弱引用对象是否还在=com.chinapay.pointconsumer.test.ReferenceTest$Employee@57f23557
    虚引用对象是否还在=null
    ------After Gc------
    弱引用对象是否还在=null
    虚引用对象是否还在=null
    ------After OOM------
    弱引用对象是否还在=null
    虚引用对象是否还在=null
    java.lang.OutOfMemoryError: Java heap space
        at com.chinapay.pointconsumer.test.ReferenceTest.testReference(ReferenceTest.java:63)
        

    另外提示一下软引用和弱引用不能同时使用,否则gc后发现弱引用引用的对象还是存在的,因为软引用只有在oom后对象才会被当做垃圾回收。

    将上面的代码改成注释弱引用后,实验结果:

    ------Before Gc------
    软引用对象是否还在=com.chinapay.pointconsumer.test.ReferenceTest$Employee@57f23557
    虚引用对象是否还在=null
    ------After Gc------
    软引用对象是否还在=com.chinapay.pointconsumer.test.ReferenceTest$Employee@57f23557
    虚引用对象是否还在=null
    ------After OOM------
    软引用对象是否还在=null
    虚引用对象是否还在=null
    java.lang.OutOfMemoryError: Java heap space

    开发中,对于一些缓存的使用,如果对业务影响不大,在出现内存不足时希望优先被回收的,可以使用SoftReference或者WeakReference。

    参考文档:Java:Java的四种引用与其中区别_VoldemortQian的博客-CSDN博客_java四种引用的区别

  • 相关阅读:
    UE5导入自定义MetaHuman虚拟人和服装并联动
    WebDAV之π-Disk派盘 + PassStore
    使用矢量坐标对自然语言建模
    从C语言到C++(五)
    2023武汉纺织大学计算机考研信息汇总
    java中的注解
    Java中long(Long)与int(Integer)之间的转换
    万物皆可集成系列:低代码对接Web Service接口
    美颜sdk在视频场景有哪些作用?
    GDPU 商务英语 [初入职场](持续更新……)
  • 原文地址:https://blog.csdn.net/figo0423/article/details/125890708