“再一次问好!”

“现在我要告诉你一件更美妙的事情:WeakReference。”

“它看起来和 SoftReference 几乎一样:”

例子
// Create a Cat object
Cat cat = new Cat();

// Create a weak reference to a Cat object
WeakReference<Cat> catRef = new WeakReference<Cat>(cat);

// Now only the catRef weak reference points at the object
cat = null;

// Now the ordinary cat variable also references the object
cat = catRef.get();

// Clear the weak reference
catRef.clear();

“弱引用还有另一个特点。”

“如果一个对象没有普通引用或软引用,而只有弱引用,那么这个对象还活着,但会在下一次垃圾回收时被销毁。”

“你能再说一遍吗?这些引用有什么区别?”

“仅由SoftReference避免死亡的对象可以在任意多次垃圾收集中存活下来,如果内存不足,它可能会被销毁。”

“仅通过WeakReference避免死亡的对象将无法在下一次垃圾收集中存活下来。但在此之前,您可以通过调用 Wea​​kReference 上的 get() 方法来获取该对象,然后调用其方法或对其执行其他操作”

“如果对象同时被 SoftReference 和 WeakReference 引用怎么办?”

“这很简单。如果至少有一个常规引用​​指向一个对象,它就被认为是活着的。顺便说一下,这样的引用称为 StrongReference。”

“如果没有常规引用指向一个对象,但 SoftReference 指向一个对象,那么它就是软可达的。”

“如果没有常规引用或 SoftReferences 指向一个对象,但 WeakReference 指向一个对象,那么它是弱可达的。”

“想一想。SoftReference 保护对象不被删除,并确保只有在内存不足时才会删除对象。WeakReference 持有对象直到下一次垃圾收集。SoftReference 提供更大的删除阻力。”

“啊,我好像明白了。”

“太好了,那我将告诉你另一个与 WeakReferences 有关的有趣的事情——WeakHashMap。”

“听起来很严重!”

“然后是一些!WeakHashMap 是一个 HashMap,其键是弱引用 (WeakReferences)。”

“也就是说,您将对象添加到这样的 HashMap 中并使用它们。一切照常。”

“只要您存储在 WeakHashMap 中的对象具有常规(强或软)引用作为键,这些对象就会存在。”

“但是假设在整个应用程序中不再有对这些对象的引用。所有让它们不死的就是WeakHashMap内部的一些WeakReferences。在下一次垃圾收集之后,这些对象将从WeakHashMap中自行消失。就像他们一样从来没有在那里。”

“我不确定我是否理解。”

“您在 WeakHashMap 中存储对象对:一个键和一个值。但是 WeakHashMap 不直接引用键,而是通过 WeakReferences。因此,当用作键的对象变得弱可达时,它们将在下一次销毁垃圾回收。因此,它们的值也会自动从 WeakHashMap 中删除。”

“使用 Wea​​kHashMap 存储有关某些对象的附加信息非常方便。”

“首先,如果您使用对象本身作为密钥,则访问信息非常容易。”

“其次,如果对象被销毁,它会连同所有相关数据一起从 HashMap 中消失。”

“例如:

例子
// Create an object to store additional information about the user
WeakHashMap<User, StatisticInfo> userStatistics = new WeakHashMap<User, StatisticInfo>();

// Put information about the user into userStatistics
User user = session.getUser();
userStatistics.put(user, new StatisticInfo (…));

// Get information about the user from userStatistics
User user = session.getUser();
StatisticInfo statistics = userStatistics.get(user);

// Remove any information about the user from userStatistics
User user = session.getUser();
userStatistics.remove(user);
  1. “在 WeakHashMap 中,键存储为 WeakReferences。”
  2. “一旦用户对象被垃圾收集器销毁,remove(user) 方法就会在 WeakHashMap 中隐式调用,并且与用户对象相关的任何信息都会自动从 WeakHashMap 中删除。”

“这看起来是个强大的工具,我可以在哪里使用它?”

“这取决于具体情况。假设您在程序中有一个线程跟踪某些由对象表示的任务的工作,并将有关它们的信息写入日志。该线程可以将受监视的对象存储在 WeakHashMap 中。尽快由于不需要这些对象,垃圾收集器会删除它们,并且对它们的引用也会自动从 WeakHashMap 中删除。”

“听起来很有趣。我已经觉得我还没有编写任何利用这种强大机制的严肃 Java 程序。但我会朝着那个方向努力。非常感谢,Ellie,给我上了这么有趣的一课。”