该类的源代码SoftReference
有这个字段:
/**
* Timestamp updated by each invocation of the get method. The VM may use
* this field when selecting soft references to be cleared, but it is not
* required to do so.
*/
private long timestamp;
根据该方法的文档,每次调用都get
必须更新timestamp
. 但它没有,我不知道为什么。作为一个实验,我写了以下类:
import java.lang.ref.SoftReference;
import java.lang.reflect.Field;
public class SoftReferenceTest {
public static void main(String[] args) throws Exception {
SoftReference<StringBuilder> softReference = new SoftReference<>(new StringBuilder());
long timestamp = getTimestamp(softReference);
for (int i = 0; i < 10; i++) {
checkTimestampChange(softReference, timestamp);
}
}
private static void checkTimestampChange(SoftReference softReference, long timestampBefore) throws Exception {
softReference.get();
Thread.sleep(100);
assert timestampBefore == getTimestamp(softReference);
}
private static long getTimestamp(Object object) throws Exception {
Field timestampField = SoftReference.class.getDeclaredField("timestamp");
timestampField.setAccessible(true);
long timestamp = timestampField.getLong(object);
timestampField.setAccessible(false);
return timestamp;
}
}
代码运行成功,没有错误。我不明白为什么。
你看过源代码
SoftReference
吗?clock
根据文档,在 GC 调用期间有一个字段会更新。和方法代码
get
您不会更改
timestamp
,因为在循环执行期间没有调用垃圾收集器。如果你明确地调用它,那么它会
timestamp
被更新:如果您删除
System.gc()
上面代码中的调用,它显然会显示在您的案例中true
(但不能保证)