【问题标题】:Weak reference benefits弱参考优势
【发布时间】:2010-09-23 13:35:01
【问题描述】:

有人能解释一下 C# 中不同类型引用的主要好处吗?

  • 弱引用
  • 软参考
  • 虚拟引用
  • 强有力的参考。

我们有一个消耗大量内存的应用程序,我们正在尝试确定这是否是一个需要关注的领域。

【问题讨论】:

  • 您的应用程序是否专门使用了 System.WeakReference 类?

标签: c# winforms memory reference weak-references


【解决方案1】:

我相信软引用和幻像引用来自 Java。长弱引用(将 true 传递给 C# 的 WeakReference 构造函数)可能被认为类似于 Java 的 PhantomReference。如果 C# 中有类似 SoftReference 的东西,我不知道它是什么。

弱引用不会延长对象的生命周期,因此一旦所有强引用都超出范围,就会对其进行垃圾回收。它们对于保持初始化成本很高的大型对象很有用,但如果它们没有被积极使用,它们应该可用于垃圾收集。

这是否有助于减少应用程序的内存消耗将完全取决于应用程序的具体情况。例如,如果您有适量的缓存对象,这些对象将来可能会或可能不会被重用,弱引用可以帮助改善缓存的内存消耗。但是,如果应用程序正在处理大量小对象,弱引用会使问题变得更糟,因为引用对象将占用尽可能多或更多的内存。

【讨论】:

【解决方案2】:

MSDN 对weak references 有很好的解释。关键引述在它说的底部:

避免使用弱引用作为 自动解决记忆问题 管理问题。相反,开发 有效的缓存策略 处理应用程序的对象。

每次我在野外看到 WeakReference 时,它​​都被用作内存管理问题的自动解决方案。对于您的应用程序问题,可能有更好的解决方案。

【讨论】:

  • 我发现引用令人困惑,因为似乎每次使用弱引用都可以由应用程序处理。在文档使用 TreeView 的示例中,应用程序可以监视用户是否使用了 TreeView 一段时间,如果没有,则将 TreeView 设置为 null,从而允许垃圾收集器处理它。这将完成相同的任务,但来自应用程序。
  • @DGGenuine:就个人而言,我认为弱引用完全没有用。我在从其他开发人员那里继承的项目中遇到过几次它们,每次我都必须完全删除它们,因为最初的开发人员不了解它们是什么以及它们的用途。
  • @MusiGenesis : I see no use at all for weak references : 直到您在启用 GC 的运行时中出现内存泄漏,因为代码中的某处存在对 Tree Node 的引用,该引用保持所有 Tree 都被引用,因此, not 垃圾回收,尽管它不再被使用。 WeakReference 用作弱引用(双关语):“如果对象仍在使用中,那么我希望能够对它做一些事情,但如果不再使用,那么我绝不想要成为让它活着的人。“这是代码卫生,确定对象的所有权或非所有权。
  • @paercebal:您似乎在说弱引用的有效用途是作为代码中其他地方的错误的黑客/解决方法。我想你可以提出这个论点。
  • 事件应该总是弱引用......但不幸的是它们不是默认的。 MS 有a class 使用弱引用处理事件,但不幸的是它的语法很糟糕。但值得庆幸的是,an event library 为弱事件提供了简单的语法,以及对事件的一些其他改进(例如,对同一事件进行多次发布很简单,消除了不必要的耦合等)
【解决方案3】:

Android development tutorial 中解释了带有 WeakReference 的精彩真实示例。

在视图(ImageView)上有一个图像(Bitmap)和图像容器。如果图像不是从内存加载(而是从磁盘、网络),那么它可以锁定 UI 线程和屏幕。为避免这种情况,可以使用异步任务。

异步任务完成时会出现问题。图像容器在那个时候可能根本没有用(屏幕改变或Android在滚动后卸载不可见的视图部分)。 WeakReference 可以在这里提供帮助,ImageView 将被垃圾收集。

class BitmapWorkerTask extends AsyncTask<Integer, Void, Bitmap> {
    private final WeakReference<ImageView> imageViewReference;

    public BitmapWorkerTask(ImageView imageView) {
        imageViewReference = new WeakReference<ImageView>(imageView);
    }
    // Method for getting bitmap is removed for code clearness

    // Once complete, see if ImageView is still around and set bitmap.
    @Override
    protected void onPostExecute(Bitmap bitmap) {
        if (imageViewReference != null && bitmap != null) {
            final ImageView imageView = imageViewReference.get();
            if (imageView != null) {
                imageView.setImageBitmap(bitmap);
            }
        }
    }
}

附:该示例是用 Java 编写的,但 C# 开发人员可以理解。
来源:http://developersdev.blogspot.ru/2014/01/weakreference-example.html

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-05-22
    • 1970-01-01
    • 1970-01-01
    • 2012-11-22
    • 2021-12-31
    • 2013-11-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多