“再一次问好!”
“现在我要告诉你一件更美妙的事情: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避免死亡的对象将无法在下一次垃圾收集中存活下来。但在此之前,您可以通过调用 WeakReference 上的 get() 方法来获取该对象,然后调用其方法或对其执行其他操作”
“如果对象同时被 SoftReference 和 WeakReference 引用怎么办?”
“这很简单。如果至少有一个常规引用指向一个对象,它就被认为是活着的。顺便说一下,这样的引用称为 StrongReference。”
“如果没有常规引用指向一个对象,但 SoftReference 指向一个对象,那么它就是软可达的。”
“如果没有常规引用或 SoftReferences 指向一个对象,但 WeakReference 指向一个对象,那么它是弱可达的。”
“想一想。SoftReference 保护对象不被删除,并确保只有在内存不足时才会删除对象。WeakReference 持有对象直到下一次垃圾收集。SoftReference 提供更大的删除阻力。”
“啊,我好像明白了。”
“太好了,那我将告诉你另一个与 WeakReferences 有关的有趣的事情——WeakHashMap。”
“听起来很严重!”
“然后是一些!WeakHashMap 是一个 HashMap,其键是弱引用 (WeakReferences)。”
“也就是说,您将对象添加到这样的 HashMap 中并使用它们。一切照常。”
“只要您存储在 WeakHashMap 中的对象具有常规(强或软)引用作为键,这些对象就会存在。”
“但是假设在整个应用程序中不再有对这些对象的引用。所有让它们不死的就是WeakHashMap内部的一些WeakReferences。在下一次垃圾收集之后,这些对象将从WeakHashMap中自行消失。就像他们一样从来没有在那里。”
“我不确定我是否理解。”
“您在 WeakHashMap 中存储对象对:一个键和一个值。但是 WeakHashMap 不直接引用键,而是通过 WeakReferences。因此,当用作键的对象变得弱可达时,它们将在下一次销毁垃圾回收。因此,它们的值也会自动从 WeakHashMap 中删除。”
“使用 WeakHashMap 存储有关某些对象的附加信息非常方便。”
“首先,如果您使用对象本身作为密钥,则访问信息非常容易。”
“其次,如果对象被销毁,它会连同所有相关数据一起从 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);
- “在 WeakHashMap 中,键存储为 WeakReferences。”
- “一旦用户对象被垃圾收集器销毁,remove(user) 方法就会在 WeakHashMap 中隐式调用,并且与用户对象相关的任何信息都会自动从 WeakHashMap 中删除。”
“这看起来是个强大的工具,我可以在哪里使用它?”
“这取决于具体情况。假设您在程序中有一个线程跟踪某些由对象表示的任务的工作,并将有关它们的信息写入日志。该线程可以将受监视的对象存储在 WeakHashMap 中。尽快由于不需要这些对象,垃圾收集器会删除它们,并且对它们的引用也会自动从 WeakHashMap 中删除。”
“听起来很有趣。我已经觉得我还没有编写任何利用这种强大机制的严肃 Java 程序。但我会朝着那个方向努力。非常感谢,Ellie,给我上了这么有趣的一课。”
GO TO FULL VERSION