Soft References in Java – Java中的软引用

最后修改: 2018年 1月 2日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

In this quick article, we’ll be talking about soft references in Java.

在这篇快速文章中,我们将讨论Java中的软引用。

We’ll explain what they are, why we need them, and how to create them.

我们将解释它们是什么,为什么我们需要它们,以及如何创建它们。

2. What Are Soft References?

2.什么是软参考资料?

A soft reference object (or a softly reachable object) can be cleared by the Garbage Collector in response to a memory demand. A softly reachable object has no strong references pointing to it.

一个软引用对象(或软可达对象)可以被垃圾收集器清除,以响应内存需求。一个软性可达对象没有指向它的强引用

When a Garbage Collector gets called, it starts iterating over all elements in the heap. GC stores reference type objects in a special queue.

当垃圾收集器被调用时,它开始迭代堆中的所有元素。GC将引用类型的对象存储在一个特殊的队列中。

After all objects in the heap get checked, GC determines which instances should be removed by removing objects from that queue mentioned above.

在堆中的所有对象被检查后,GC通过从上述队列中删除对象来决定哪些实例应该被删除。

These rules vary from one JVM implementation to another, but the documentation states that all soft references to softly-reachable objects are guaranteed to be cleared before a JVM throws an OutOfMemoryError.

这些规则因不同的JVM实现而异,但文档指出,在JVM抛出OutOfMemoryError.之前,保证所有对软性可访问对象的软性引用都被清除。

Though, no guarantees are placed upon the time when a soft reference gets cleared or the order in which a set of such references to different objects get cleared.

不过,对于软引用被清除的时间或一组不同对象的引用被清除的顺序,没有任何保证。

As a rule, JVM implementations choose between cleaning of either recently-created or recently-used references.

作为一项规则,JVM的实现可以选择清理最近创建的引用或最近使用的引用。

Softly reachable objects will remain alive for some time after the last time they are referenced. The default value is a one second of lifetime per free megabyte in the heap. This value can be adjusted using the -XX:SoftRefLRUPolicyMSPerMB flag.

软可达对象在最后一次被引用后的一段时间内将保持活力。默认值是堆中每一空闲兆字节的寿命为一秒。这个值可以使用-XX:SoftRefLRUPolicyMSPerMB标志来调整。

For example, to change the value to 2.5 seconds (2500 milliseconds), we can use:

例如,要将数值改为2.5秒(2500毫秒),我们可以使用。

-XX:SoftRefLRUPolicyMSPerMB=2500

In comparison to weak references, soft references can have longer lifetimes since they continue to exist until extra memory is required.

与弱引用相比,软引用可以有更长的生命期,因为它们会继续存在,直到需要额外的内存。

Therefore, they’re a better choice if we need to hold objects in memory as long as possible.

因此,如果我们需要尽可能长时间地将对象保存在内存中,它们是一个更好的选择。

3. Soft References’ Use Cases

3.软参考的使用案例

Soft references can be used for implementing memory-sensitive caches where memory management is a very important factor.

软引用可用于实现对内存敏感的缓存,其中内存管理是一个非常重要的因素。

As long as the referent of a soft reference is strongly reachable, that is – is actually in use, the reference won’t be cleared.

只要软引用的引用者是强可及的,也就是说–确实在使用,引用就不会被清除。

A cache can, for example, prevent its most recently used entries from being discarded by keeping strong referents to those entries, leaving the remaining entries to be discarded at the discretion of the Garbage Collector.

例如,一个缓存可以通过保持这些条目的强参考性来防止其最近使用的条目被丢弃,剩下的条目则由垃圾收集器决定是否丢弃。

4. Working With Soft References

4.使用软参考资料

In Java, a soft reference is represented by the java.lang.ref.SoftReference class.

在Java中,软引用由java.lang.ref.SoftReference类表示。

We have two options to initialize it.

我们有两个选择来初始化它。

The first way is to pass a referent only:

第一种方式是只传递一个指代物。

StringBuilder builder = new StringBuilder();
SoftReference<StringBuilder> reference1 = new SoftReference<>(builder);

The second option implies passing a reference to a java.lang.ref.ReferenceQueue as well as a reference to a referent. Reference queues are designed for making us aware of actions performed by the Garbage Collector. It appends a reference object to a reference queue as it decides to remove the referent of this reference.

第二个选项意味着将一个引用传递给java.lang.ref.ReferenceQueue以及一个引用对象的引用。引用队列是为了让我们了解垃圾收集器所执行的操作而设计的。当它决定删除该引用的引用对象时,它将引用对象追加到引用队列中。

Here’s how to initialize a SoftReference with a ReferenceQueue:

下面是如何用一个ReferenceQueue来初始化一个SoftReference

ReferenceQueue<StringBuilder> referenceQueue = new ReferenceQueue<>();
SoftReference<StringBuilder> reference2
 = new SoftReference<>(builder, referenceQueue);

As a java.lang.ref.Reference, it contains the methods get and clear to get and reset a referent respectively:

作为一个java.lang.ref.Reference,它包含了getclear方法,分别获取和重置一个引用。

StringBuilder builder1 = reference2.get();
reference2.clear();
StringBuilder builder2 = reference2.get(); // null

Each time we work with this kind of references, we need to make sure that a referent, returned by the get, is present:

每次我们处理这种引用时,我们需要确保由get返回的引用是存在的。

StringBuilder builder3 = reference2.get();
if (builder3 != null) {
    // GC hasn't removed the instance yet
} else {
    // GC has cleared the instance
}

5. Conclusion

5.结论

In this tutorial, we got familiar with the concept of soft references and their use cases.

在本教程中,我们熟悉了软参考的概念和它们的使用情况。

Also, we’ve learned how to create one and work with it programmatically.

此外,我们还学会了如何创建一个并以编程方式使用它。