ToB企服应用市场:ToB评测及商务社交产业平台

标题: Java中的各种引用类型以及部分引用的相关例子 [打印本页]

作者: 尚未崩坏    时间: 2024-5-17 06:28
标题: Java中的各种引用类型以及部分引用的相关例子
引用类型

在Java中,引用类型主要有四种,分别是:强引用(Strong Reference)、软引用(Soft Reference)、弱引用(Weak Reference)和虚引用(Phantom Reference)。这些类型通常与垃圾回收机制有关,用来形貌对象的生命周期和可达性。下面详细先容每一种引用类型:
弱引用

公道的使用弱引用可以解决部分内存泄漏的问题。
ThreadLocal

ThreadLocal是Java中多线程编程中一个重要的类。它能够将值存储在当火线程中,不与其他线程共享,同时让编码者能够超过多个层级获取到该值。比如在Web服务中我们可以使用ThreadLocal存储哀求的id,从而使得该次哀求中所有的日志输出都携带上哀求id,方便后续的非常排查;又或是如同Spring Transaction的实现一样,将Connection存储在ThreadLocal,让一个线程绑定一个Connection,实现事务机制。
ThreadLocal实现解析:
ThreadLocal的本身的实现就是弱引用使用的一个经典案例。


上面是ThreadLocal的get方法,可以看到它先是获取当前的线程之后再获取了线程中的ThreadLocalMap实例,接着从该Map中获取到具体的值。也就是说ThreadLocal实际上是通过每一个线程中存储一个单独的ThreadLocalMap实例来实现的。
接下来查看ThreadLocalMap的源码:

ThreadLocalMap是ThreadLocal的一个内部类,它的Entry继承自WeakReference,结合Entry的构造方法可以发现Entry是持有了一个指向ThreadLocal实例的弱引用并且使用该弱引用作为Key。如此实现,当外部没有指向该ThreadLocal的软引用、强引用之后,该ThreadLocal实例将会被直接回收。这样做带来的一个好处就是,在我们不须要该ThreadLocal对象之后,这个ThreadLocal能够及时的被GC回收,包管不会因此导致内存泄漏。
有一个经典问题:ThreadLocal是如何导致内存泄漏的?
起首ThreadLocal自身提供了remove方法,上面说了ThreadLocalMap的实现包管了程序不会因为ThreadLocal导致内存泄漏,那这个问题是不是与上面所说的辩论了?其实否则,从前面的代码可以看到ThreadLocalMap的Entry.key虽然是弱引用,但是Entry.value并不是弱引用。当ThreadLocal被GC回收之后,并且我们在回收之前没有表现调用remove方法,我们便无法访问到对应的Entry,从而将该Entry删除,那么始终便存在一条这样的引用链路Thread->ThreadLocalMap->Entry->value,在线程被结束之前该value以及该Entry无法被回收,若是该线程无法没及时结束,那么就有可能导致内存泄漏。
可能会有人问为何不将Entry以及Entry.value也实现为弱引用?答案也很简单,若是实现为弱引用,那么很多情况下通过ThreadLocal获取一开始存入的值都将为null,在非特殊情况下,
ThreadLocal的作用可以说是即是零。
综上所述,在编码的时候,只要公道的调用remove方法其实就能够避免因ThreadLocal导致的内存泄漏。
WeakHashMap

Java中还有其他地方也使用到了弱引用,比如WeakHashMap。
使用案例:
  1. import java.util.WeakHashMap;
  2. public class WeakCache {
  3.     private final WeakHashMap<Key, BigObject> weakMap = new WeakHashMap<>();
  4.     public void put(Key key, BigObject object) {
  5.         weakMap.put(key, object);
  6.     }
  7.     public BigObject get(Key key) {
  8.         return weakMap.get(key);
  9.     }
  10.     // Key类用于映射的键
  11.     class Key {
  12.         // ...
  13.     }
  14.     // BigObject类是一个大对象,占用大量内存
  15.     class BigObject {
  16.         // ...
  17.     }
  18. }
复制代码
在WeakCache 类中,通过WeakHashMap 实现了一个弱引用键的缓存。当Key没有在其他地方被强引用时,这个Key-Value映射随时都可能被自动移除。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4