在python的标准类库中发现有weakref这个模块,比较有趣。依稀想起在java中似乎也有个叫做WeakReference的类,只是当时没有太留心,此时好奇心起,在网上找到这篇文章,讲的挺好,摘要一下。
在Java 1.2中就引入了java.lang.ref这个包,WeakReference就属于这个包。WeakReference是干嘛的呢,一言弊之,它是和Java中的垃圾回收相关的。如果一个对象只有WeakReference引用它,那么这个对象就可能被垃圾回收器回收。
在什么场合下应用WeakReference呢?
有时我们会碰到一些不能继承的类,如final class, 或者通过Factory创建的对象,它对外只暴露一个接口,我们无法知道它的具体实现类,自然也无法继承它。假如我们要使用一个Widget类,因为某种 缘故,我们无法继承该类来加入某个功能。但是,我们必须将每个Widget对象和某个序列号关联,而Widget本身没有serial number这个属性,这时该怎么做呢?
你也许已经想到,用HashMap!对,像这样:
1.serialNumberMap.put(widget, widgetSerialNumber);
这看起来工作的很好。但是,有个问题:当我们不再需要某个Widget的serial number信息,此时应该从HashMap中将这个Entry移除,如果我们忘记了怎么办?因为HashMap中持有对这个对象的引用,这个对象永远不 会被垃圾回收器回收,这就造成了内存泄漏!这意味着我们需要像没有垃圾回收功能的语言一样,手动管理内存!但是我们用的是Java.....
另一个很常见的问题是缓存。如果使用强引用,那么我们缓存的对象就会一直滞留在内存中,不会被回收,除非我们手动的将其从缓存中移除。此外,这还需要我们决定何时从缓存中移除对象,又一个手动管理内存的问题!
此时,WeakReference就显示出它的价值了。如何创建一个WeakReference呢?很简单:
1.WeakReference<widget> weakWidget = newWeakReference<widget>(widget);
2.Widget w = weakWidget.get();
要注意的是,当调用weakReference.get()可能返回null(意味着指向的对象已经被回收)。其实,对于Widget serial number这个问题,最简单的方法是使用WeakHashMap,它的使用和普通的HashMap完全一样,不同点在于,WeakHashMap的key被实现为一种WeakReference(注意,是key而不是value),当key对象被回收后,WeakHashMap会自动将对应的entry移除。更精确的说,对于一个给定的键,其映射的存在并不阻止垃圾回收器对该键的回收。
Java中有四种类型的引用,按照强弱关系依次为:Strong Reference>Soft Reference>WeakReference> Phantom Reference。
其中,我们平常用的就是Strong Reference,而Phantom Reference很少用到,因此这里不去研究了,那么什么是Soft Reference呢?
Soft Reference和weak reference的区别是:一旦gc发现对象是weak reference可达就会把它放到ReferenceQueue中,然后等下次gc时回收它;当对象是Soft reference可达时,gc可能会向操作系统申请更多内存,而不是直接回收它,当实在没辙了才回收它。像cache系统,最适合用Soft reference。让gc来替我们决定什么时候回收对象以及回收哪些对象。
分享到:
相关推荐
SoftReference、WeakReference和PhantomReference分析和比较 在 Java 中,引用类型分为强引用、软引用、弱引用和虚引用四种。强引用是我们最常用的引用类型,而软引用、弱引用和虚引用则是 Java 为我们提供的三种...
消除过期引用可以使用多种方法,例如,使用 WeakReference 或 SoftReference,或者使用 finalize() 方法来回收对象。 其他知识点 其他知识点还包括泛型、枚举和注解、Lambda 和 Stream、方法、通用编程、异常、...
Java从1.2版本开始引入了四种引用,分别是强引用(StrongReference)、软引用(SoftReference)、弱引用(WeakReference)和虚引用(PhantomReference)。这四种引用的级别由高到低依次为:强引用 > 软引用 > 弱引用...
在实际应用中,LRU算法不仅可以用于操作系统中的页面替换,还可以应用于数据库查询缓存、编程语言的内存管理(如Java的SoftReference和WeakReference)以及Web服务器的静态资源缓存等场景。 总的来说,Java实现LRU...
这些引用类型通过`java.lang.ref`包中的`SoftReference`、`WeakReference`和`PhantomReference`类实现,而`ReferenceQueue`类用于与这三种引用类型一起工作,记录引用对象被回收的信息。 以下是一个简单的例子展示...
合理使用` WeakReference`和`SoftReference`,及时清理不再使用的对象,可以帮助防止内存泄漏。 5. **异常处理不当**:忽略异常或者使用`Exception`作为捕获所有异常的类型,会隐藏问题,阻碍调试。应精确捕获和...
本文将深入探讨这个包中的四种主要引用类型:StrongReference、SoftReference、WeakReference 和 PhantomReference,以及它们的特性、用法和作用。 首先,强引用(StrongReference)是我们在日常编程中最常见的引用...
System.out.println(softReference.get()); // 输出 "abc" str = null; // 断开强引用 System.gc(); // 请求GC // 如果当前内存充足,则仍然可以获取到软引用的对象 System.out.println(softReference.get());...
4. 使用WeakReference和SoftReference,WeakReference和SoftReference可以帮助避免内存泄漏。 Java的垃圾回收机制可以自动回收内存中的垃圾,避免内存泄漏,但是程序员需要注意避免内存泄漏的几点,以确保程序的...
`java.lang.ref` 提供了与垃圾收集器交互的引用对象类,如 `WeakReference`, `SoftReference`。 `java.lang.reflect` 允许程序在运行时检查类和对象的结构。 `java.math` 包提供高精度的数学运算,如 `BigInteger`...
6. **WeakReference与SoftReference**:弱引用和软引用在内存管理中起着重要作用,它们不会阻止垃圾回收,但软引用在内存不足时才会被回收。 7. **Map接口**:除了HashMap和TreeMap,还有LinkedHashMap,它保持插入...
- **关键类**:`Reference`, `SoftReference`, `WeakReference` ##### 3.19 `java.lang.reflect` - **用途**:提供用于获取类和对象反射信息的类和接口。 - **关键类**:`Class`, `Constructor`, `Field` ##### ...
同时,`WeakReference`和`SoftReference`可以帮助我们实现基于垃圾收集的资源回收策略。 为了确保公共资源模块的可测试性,应遵循依赖注入原则。Spring框架提供了强大的依赖注入功能,通过`@Autowired`注解和Bean...
4. WeakReference 与 SoftReference: WeakReference 和 SoftReference 都可以用于提高 GC 和内存的效率,但是 WeakReference 一旦失去最后一个强引用,就会被 GC 回收,而软引用虽然不能阻止被回收,但是可以延迟到...
- 为了提高性能,可以引入缓存机制,如使用Java的WeakReference、SoftReference,或者引入第三方缓存框架如Redis或Memcached。 9. **分布式数据库**: - 高可用性和扩展性要求数据库可能需要分布式部署,Java的...
理解Java内存模型,合理设置堆大小,避免创建过大的对象,及时清理不再使用的对象,使用WeakReference和SoftReference管理对象,可以帮助防止内存溢出。 以上仅是部分常见的Java Bug模式,实际开发中还会有更多复杂...
4. **弱引用和软引用**:在java.lang.ref包中增加了WeakReference和SoftReference类,提供了一种内存管理策略,有助于避免内存泄露。 5. **改进的集合框架**:包括HashSet、HashMap和ArrayList等类的性能优化,以及...
Java 中的弱引用(WeakReference)是一种特殊的引用类型,它可以帮助我们更好地管理内存和避免内存泄漏。在 Java 中,当一个对象被创建时,它被放在堆(Heap)中。当垃圾回收器(GC)运行时,如果发现没有任何引用...