弱参考

问候,

介绍

Java因其垃圾回收机制而受到赞扬(并鄙视)。 在

年和几种Java版本GC机制已经从简单的标记变为

和清除收集器导致早期的Java程序暂时冻结

有时它不应该冻结为高度复杂的多线程,

复杂的“世代清除”收集机制,难以完成工作

其余的应用程序或用户可以注意到。

与许多其他编程相比,Java的内存管理轻而易举

语言。 事情仍然可能出错或失控:内存泄漏。 确切地说,

这实际上不是C语言程序中的“泄漏”:


int main() {
   char* p= malloc(42);
   p= malloc(54);
} 
后代丢失了前42个字节,因为程序中没有任何内容

“指向”或“引用”了。 在Java中不是这样:Java中的内存泄漏

意味着某些东西仍然指向持有的特定内存

一个对象值,但我们不知道还有其他东西指向它。 但是我们

确保某些东西指向它,否则垃圾收集器将具有

找到了。

Java内存泄漏更像是“粘性内存”,例如在下面的某处嚼口香糖

您的鞋子:您不知道它在那儿,但它仍然在那儿。

如果您不小心在某种循环中实施了此类不良行为

您可以指望它会在不久的将来出现OutOfMemory异常

Java虚拟机抛出的垃圾邮件将使您的应用程序丧命。

一些核心课程提供了一些基础知识,可以对

上述情况。 接下来的段落描述了这些构建块。

参考文献薄弱

从功能上讲,WeakReference类仅此而已:


public class WeakReference<T> {
    private T referent;
    public WeakReference(T referent) { this.referent= referent; }
    public T get() { return referent; }
} 
请注意,这不是WeakReference类的真正源代码,它只是

展示了此类对象在功能上的行为。

真正的功能并不多:您可以将WeakReference传递给任何对象

在构造时类型为T的对象,以后可以将对象T取回

你再次想要它; 没关系

幕后还有很多事情发生:实例化WeakReference时

对象,将其自身注册到垃圾收集器,即与之通信

我们背后的敌人。

激活垃圾收集器后,它会跟踪引用的对象

所有的WeakReferences。 如果这些对象除以外没有其他引用

由WeakReferences持有的参考文献,它们是在

垃圾收集器,即WeakReference对象中的引用T设置为

null,该对象因后代而丢失。

如果T对象被不符合垃圾回收条件的另一个对象引用

T对象本身将是安全的。

总结:如果对对象的唯一引用是通过WeakReference对象,

该对象仍然有资格进行垃圾收集。

如果没有其他内容引用WeakReference对象,则引用对象将仅

如果其他事物直接引用该引用对象,则该方法是安全的。 弱参考

但是该对象有资格进行垃圾收集。 用外行的话来说:弱引用

是派对装腔作势者:当他们最后引用物体时,他们怯ly

将该对象移交给垃圾收集器收割机。

粘性物体

粘滞对象失败的常见情况是发生Swing对象时

注册为其他对象的侦听器。 没有注册对象时

不再需要它们,其他对象仍将它们称为侦听器,以

他们已注册。

令人讨厌的是那些注册的侦听器不知道什么时候不知道

该应用程序不再需要。 应用到

“手动”在不再需要侦听器时将其删除,并且,

这样做容易出错(程序员是人类,人类很愚蠢)

因为他们经常犯错误)。

在这里,WeakReferences可能会有所帮助:想象我们这样做:而不是注册

一个对象的侦听器,我们注册一个WeakReference并制作原始对象

监听器,WeakReference对象本身的引用对象。 诀窍的核心

是当WeakReference对象的'get()'方法返回null时,

引用对象已被垃圾回收。

为了示例,让我们处理需要注册的ActionListener

到AbstractButtons。

AbstractButton包含以下方法的实现:


public void addActionListener(ActionListener listener);
public void removeActionListener(ActionListener listener); 
仅仅因为AbstractButton恰好是其中所有内容的基类

使用ActionListeners的Swing仅需要为

AbstractButton类(为Swing的设计加油!)。

如果我们想将WeakReference注册为ActionListener,则*

一个ActionListener本身。 没问题,这里是:


public class ActionReference extends WeakReference<ActionListener>
                 implements ActionListener {
    private AbstractButton button; 
    ActionReference(ActionListener listener, AbstractButton button) {
        super(listener);
        this.button= button;
        button.addActionListener(this);
    }
    public void actionPerformed(ActionEvent event) {
        ActionListener listener= get();
        if (listener == null)
            button.removeActionListener(this);
        else
            listener.actionPerformed(event);
    }
} 
构造函数将AbstractButton和ActionListener作为其参数。

它跟踪按钮并将其自身注册为ActionListener。

当按钮触发事件时,ActionReference的actionPerformed方法为

调用。 它检查实际的ActionListener是否已被垃圾回收

集。 如果是这样,它将从按钮中注销自己。 如果真正的侦听器仍然存在,

将该事件委托给真实的侦听器,就像将其注册到

直接点击。

对于任何“按钮”和任何“侦听器”,侦听器的注册方式如下:


new ActionReference(listener, button); 
这就是您要做的一切:当不再需要侦听器时,我们的ActionReference

通过从事件源中删除自身来解决此问题。 请注意,我没有使用

事件对象本身的“ getSource()”方法。 这样可以防止移除

来自错误对象的ActionListener,如果事件的触发是综合的

由应用程序本身。

这个单一的小类可以防止内存泄漏或应用程序中的“粘性对象”。

我相信您现在可以弄清楚如何安全处理其他类型的事件。

希望直到下周

亲切的问候,

乔斯

From: https://bytes.com/topic/java/insights/705335-weakreferences

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值