参考利益薄弱


73

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

  • 参考文献薄弱
  • 软参考
  • 幻影参考
  • 有力的参考。

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


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

Answers:


61

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

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

这对于减少应用程序的内存消耗是否有用将完全取决于应用程序的具体情况。例如,如果您有相当数量的高速缓存对象在附近徘徊,这些对象将来可能会或可能不会被重用,则弱引用可以帮助改善高​​速缓存的内存消耗。但是,如果应用程序使用大量小对象,则弱引用将使问题更严重,因为引用对象将占用更多或更多的内存。



35

MSDN对弱引用有很好的解释。关键语录在底部,上面写着:

避免使用弱引用作为 内存 管理问题自动解决方案。而是开发一种有效的缓存策略来处理应用程序的对象。

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


2
我发现引号令人困惑,因为似乎弱引用的每次使用都可以由应用程序处理。在文档使用TreeView的示例中,应用程序可以监视用户是否已使用TreeView一段时间,如果没有使用,请将TreeView设置为null,以使垃圾收集器可以使用它。那将完成相同的任务,但是要从应用程序中完成。
卡尔·G

2
@DGGenuine:就我个人而言,我认为弱引用毫无用处。我在从其他开发人员继承的项目中遇到了几次,每种情况下我都必须将其完全删除,因为原始开发人员不了解它们的含义和用途。
MusiGenesis 2012年

10
@MusiGenesis: I see no use at all for weak references:您必须在您启用GC-运行时内存泄漏,因为在某处的代码存在于树节点的引用这使所有的树引用,因此不能当作垃圾收集尽管它不再使用。WeakReference用作弱引用(用于双关语):“如果该对象仍在使用中,那么我希望能够对其进行处理,但是如果它不再存在,则绝不是我想成为的对象。一个使它保持生命的方法。 “这是代码卫生,确定对象的所有权或非所有权。
paercebal 2012年

9
@paercebal:您似乎是说对弱引用的有效使用是作为代码中其他地方的bug的破解/解决方法。我想你可以提出这样的论点。
MusiGenesis'8

6
事件应该始终是弱引用...但是不幸的是,它们不是默认情况。MS有一个使用弱引用处理事件的类,但是不幸的是,它的语法很糟糕。但值得庆幸的是,有一个事件库为弱事件提供了简单的语法,并对事件进行了其他一些改进(例如,简单地对同一事件进行多次发布,消除不必要的耦合等)
BlueRaja-Danny Pflughoeft

5

Android开发教程中介绍了带有WeakReference的出色示例。

视图(ImageView)上有一个图像(位图)和图像容器。如果图像不是从内存(例如从磁盘,网络)加载的,则可以锁定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);
            }
        }
    }
}

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.