iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > ASP.NET >.Net中的弱引用字典WeakDictionary和ConditionalWeakTable介绍
  • 119
分享到

.Net中的弱引用字典WeakDictionary和ConditionalWeakTable介绍

2024-04-02 19:04:59 119人浏览 薄情痞子
摘要

有的时候,我们需要给某些数据添加一些附加信息,一种常用的做法是使用一个Dictionary在填充这些附加信息如: var data = new Data(); var

有的时候,我们需要给某些数据添加一些附加信息,一种常用的做法是使用一个Dictionary在填充这些附加信息如:

    var data = new Data();
    var tag = new Tag();

    var dictionary = new Dictionary<Data, Tag>();
    dictionary[data] = tag;

这么做本身没有什么问题,但是却又一个不小的隐患,那就是在dictionary中保存着了data和tag的引用。当data不再使用的时候,需要将其从dictionary中移除,否则data和tag得不到释放。我们可以用如下代码说明这个问题:(注意,由于Debug模式有时会影响GC,本文代码需行在Release模式下)

    class Tag
    {
        public Tag()
        {
            Console.WriteLine("Create Tag");
        }

        ~Tag()
        {
            Console.WriteLine("Release Tag");
        }
    }

    class Data
    {
        public Data()
        {
            Console.WriteLine("Create Data");
        }

        ~Data()
        {
            Console.WriteLine("Release Data");
        }
    }

    static void Main(string[] args)
    {
        var data = new Data();
        var tag = new Tag();

        var dictionary = new Dictionary<Data, Tag>();
        dictionary[data] = tag;

        data = null;
        GC.Collect();

        Console.WriteLine("After GC");
        Console.ReadLine();
        Console.WriteLine(dictionary);
    }

从运行结果中可以看出,只有创建的输出,而没有释放的输出。这个就属于资源泄漏了。虽然可以通过手动在dictionary中删除data来实现资源的释放,但是这样就要求我们手动管理对象的生命周期了,而这往往不是一个比较容易做到的事情。

究其原因,是由于dictionary中保持着强引用、导致GC不会对其进行回收。找到了这个原因后,那就有相应的对策了,那就是改用弱引用来建立关联,这样数据就会被GC释放了。这种观念关系我们通常称为弱字典——WeakDictionary。弱字典也是保存着Key和Value的键值对,它满足如下需求:

  • 字典中保存着Key的弱引用,即使不释放Key值,也可以被GC回收。

  • 字典中保存的Value的强引用,Key没有被GC回收前,Value不会被GC回收。

  • 当Key被GC回收时,关联关系从字典中移除,Value也能被GC回收。

知道了需求后,接下来就可以对Dictionary进行简单的封装,将其改造成弱字典了。

    static void Main(string[] args)
    {
        var data = new Data();
        var tag = new Tag();

        var dictionary = new Dictionary<WeakReference<Data>, Tag>();
        var key = new WeakReference<Data>(data);
        dictionary[key] = tag;

        data = null;
        GC.Collect();

        Console.WriteLine("After GC");
        Console.ReadLine();
        Console.WriteLine(dictionary);
    }

运行这段代码后,我们就会发现,Data数据能释放了,但是并不完善,具体体现在如下方面:

  • Tag保存的仍然是强引用,得不到释放

  • Key数据并不是Data类型了,存在一个检索的问题,否则无法CRUD。

对于第一个问题,可以通过一个Timer来定时清理已经释放了的Key来解决;对于第二个问题,则需要在内部通过key来建立Hash表来解决。具体的实现还有点麻烦,也会引入一些新的问题,这里就不继续列举了。

之所以不继续改造下去了,是因为这里我是在造重复轮子,.net的BCL中本身就已经提供了一个弱字典——ConditionalWeakTable,通过ConditionalWeakTable改造上述代码如下:

    static void Main(string[] args)
    {
        var data = new Data();
        var tag = new Tag();

        var dictionary = new ConditionalWeakTable<Data, Tag>();
        dictionary.Add(data, tag);

        data = null;
        GC.Collect();

        Console.WriteLine("After GC");
        Console.ReadLine();
        Console.WriteLine(dictionary);
    }

从运行结果来看,GC结束后,Key和Value都被GC回收掉了(再次强调,需要运行在Release版本下)。

这个类放置在System.Runtime.CompilerServices下,也很少见到有书里面介绍到它。这里我就简单的介绍一下其接口吧:

    dictionary.Add(data, tag);    //添加    
    dictionary.TryGetValue(data, out tag);    //查询
    dictionary.Remove(data);    //删除

这三个是它比较常见的接口,另外还有两个不大用的接口,这里就不多介绍了。

最后,简单的试了它的性能,基本上和Dictionary差不多,查询效率还是非常高的,内部应该也是一个Hash表。

到此这篇关于.Net弱引用字典WeakDictionary和ConditionalWeakTable的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持编程网。

--结束END--

本文标题: .Net中的弱引用字典WeakDictionary和ConditionalWeakTable介绍

本文链接: https://www.lsjlt.com/news/152616.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • .Net中的弱引用字典WeakDictionary和ConditionalWeakTable介绍
    有的时候,我们需要给某些数据添加一些附加信息,一种常用的做法是使用一个Dictionary在填充这些附加信息如: var data = new Data(); var...
    99+
    2024-04-02
  • .Net中的弱引用字典WeakDictionary和ConditionalWeakTable怎么使用
    这篇文章主要介绍“.Net中的弱引用字典WeakDictionary和ConditionalWeakTable怎么使用”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“.Net中的弱引用字典WeakDi...
    99+
    2023-07-02
  • Java中的强引用,软引用,弱引用,虚引用的作用介绍
    目录1.强引用( Strong Reference )2.软引用( Soft Reference )3.弱引用( Weak Reference )4.虚引用( PhantomRefe...
    99+
    2024-04-02
  • python元组和字典的介绍
    这篇文章主要介绍“python元组和字典的介绍”,在日常操作中,相信很多人在python元组和字典的介绍问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”python元组和字典的介绍”的疑惑有所帮助!接下来,请跟...
    99+
    2023-06-01
  • C++中引用和const关键字介绍
    目录引用常引用const关键字用法1)定义常量2)定义常量指针3)定义常引用总结引用 下面的写法定义了一个引用,并将其初始化为引用某个变量。类型名 & 引用名 = 某变量名;...
    99+
    2024-04-02
  • python里字典的用法介绍
    一、什么是字典 字典是python里的一种数据类型,特点是元素的无序性,和键key的唯一性。字典的创建方法是{key:values},字典里的键key只能是不可变的数据类型(整型,字符串或者是元组),值values可以是任何数据类型。字典...
    99+
    2023-01-30
    字典 python
  • .Net 6中WebApplicationBuilder介绍和用法
    目录介绍正文ConfigureHostBuilderBootstrapHostBuilderWebApplicationBuilder构造函数WebApplicationBuilde...
    99+
    2024-04-02
  • .NET中的字符串驻留池介绍
    在.NET中,对于相同的字符串,.NET会将它们指向同一个地址,它们是相同的实例。.NET中的字符串并不会更新,当更改一个字符串变量时,由于字符串的不可变性,.NET实际上是新创建一...
    99+
    2024-04-02
  • Python中字典的相关操作介绍
    字典的添加与修改 # coding:utf-8 if __name__ == '__main__': example = {'name': 'xie', 'age': 27...
    99+
    2024-04-02
  • JavaScript中的弱引用和强引用是什么
    本篇内容介绍了“JavaScript中的弱引用和强引用是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!...
    99+
    2024-04-02
  • 如何用生活里字典的实际应用来介绍Python基础中字典的知识
    如何用生活里字典的实际应用来介绍Python基础中字典的知识,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。一、前言如果有列表 ,需要对"xiaoWan...
    99+
    2023-06-15
  • python 中defaultdict()对字典进行初始化的用法介绍
    目录用法讲解:1. 不使用defaultdict(): 2. 使用defaultdict(): 用法讲解: 一般情况下,在使用字典时,先定义一个空字典(如dict...
    99+
    2024-04-02
  • Python中字典的基础介绍及常用操作总结
    目录1.字典的介绍2.访问字典的值(一)根据键访问值(二)通过get()方法访问值3.修改字典的值4.添加字典的元素(键值对)5.删除字典的元素6.字典常见操作1.len 测量字典中...
    99+
    2024-04-02
  • Python中的引用与copy介绍
    目录Python中的引用和copy1、引用整型数据及列表2、传递引用3、copy模块中的copy()和deepcopy()Python中的引用和copy 1、引用整型数据及列表 这里...
    99+
    2024-04-02
  • Java中static关键字的介绍和用法
    本篇内容主要讲解“Java中static关键字的介绍和用法”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java中static关键字的介绍和用法”吧!用类名去调用static有两层含义: 可以理...
    99+
    2023-06-02
  • .NET中堆栈和堆的特点与差异介绍
    一、前言 .NET提供了垃圾回收机制,使程序员从内存管理中被解放出来。但这并不代表程序员就无须了解分配的对象是如何被回收的。更重要的是,一些非托管的资源仍然需要程序员小心地分配与回收...
    99+
    2024-04-02
  • JavaScript 中的引用类型Date 和RegExp的详细介绍
    目录引用类型 & 引用值的理解Date 引用类型Date.parse()方法Date.UTC()方法继承的方法RegExpRegExp 实例方法exec()test()继承的...
    99+
    2024-04-02
  • Python中关于字典的常规操作范例以及介绍
    目录1.字典的介绍2.访问字典的值(一)根据键访问值(二)通过get()方法访问值3.修改字典的值4.添加字典的元素(键值对)5.删除字典的元素6.字典常见操作1.len 测量字典中...
    99+
    2024-04-02
  • js中值类型和引用类型的区别介绍
    1.JavaScript中的变量类型有哪些? (1)值类型(基本类型):字符串(string)、数值(number)、布尔值(boolean)、undefined、null ...
    99+
    2024-04-02
  • Linux Shell中几种括号和引号的用法介绍
    本篇内容介绍了“Linux Shell中几种括号和引号的用法介绍”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!Shell 脚本中经常需要用到...
    99+
    2023-06-16
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作