首页 > 编程语言 >C#中的弱引用

C#中的弱引用

时间:2023-03-11 11:15:22浏览次数:43  
标签:Console C# weak 回收 对象 GC 引用

弱引用保持的是一个GC“不可见”的引用,是指弱引用不会增加对象的引用计数,也不会阻止垃圾回收器对该对象进行回收。因此,弱引用的目标对象可以被垃圾回收器回收,而弱引用本身不会对垃圾回收造成任何影响。

弱引用的原理是,在堆上分配的每个对象都有一个头部信息,用于存储对象的类型信息、对象的大小等信息。在头部信息中,还会有一个标志位用于表示对象是否被引用。当一个对象被创建时,该标志位为“未引用”。当该对象被弱引用引用时,该标志位不会变为“已引用”,即该对象仍然会被当做未引用的对象进行处理。被强引用后,会被标记为”已引用“,当所有的强引用都消失时,该标志位会变为“未引用”,即该对象已经没有任何强引用指向它,标记的工作由GC来完成。

在垃圾回收时,GC会根据标记-清除算法对堆中的对象进行扫描和标记,标记所有仍然被引用的对象,然后回收所有未被标记的对象。对于被弱引用引用的对象,由于弱引用不会增加对象的引用计数,也不会阻止垃圾回收器回收该对象,因此在回收时,该对象会被当做未被引用的对象进行处理,然后被回收。

总之,弱引用保持的是一个GC“不可见”的引用,即弱引用不会影响垃圾回收器对目标对象的回收,因此可以用于实现一些场景,例如缓存、对象池等场景,避免长时间占用内存或造成内存泄漏。

var sb = new StringBuilder("weak");
            Console.WriteLine("before GC");
            Console.WriteLine(sb);
            GC.Collect();//强制垃圾回收
            Console.WriteLine("after GC");
            Console.WriteLine(sb);
            Console.ReadLine();

output

before GC
weak
after GC
weak

以下代码在release模式下:

var sb = new StringBuilder("weak");
            var weak = new WeakReference(sb);
            Console.WriteLine("before GC");
            Console.WriteLine(weak.Target);
            GC.Collect();
            Console.WriteLine("after GC");
            if (weak.Target == null)
            {
                Console.WriteLine("now it has been cleared...");
            }
            else
            {
                Console.WriteLine(weak.Target);
            }

output:

before GC
weak
after GC
now it has been cleared...

在 debug 模式下,GC.Collect 方法仍然会工作,但是它的行为可能会受到一些影响。

在 debug 模式下,编译器会添加额外的调试信息到代码中,这些信息可能会影响垃圾回收器的行为。例如,编译器可能会保留一些对象的引用,以便调试器可以访问它们,这可能会导致这些对象不会被垃圾回收器回收,直到调试器不再需要它们为止。因此,当调用 GC.Collect 方法时,由于存在调试信息的影响,可能会出现一些对象无法被立即回收的情况。

此外,在 debug 模式下,垃圾回收器的性能也可能会受到一定的影响,因为编译器会添加额外的代码和调试信息,导致程序变得更加复杂和庞大,从而使垃圾回收器需要更长的时间来扫描和回收对象。

因此,如果需要在 debug 模式下进行垃圾回收操作,应该仔细考虑其影响,并进行充分的测试,以确保程序的正确性和性能。同时,还可以考虑使用其他的调试工具和技术来诊断和解决问题,避免对程序的垃圾回收行为产生不必要的影响。

所以,以上代码在debug模式下,会有截然不同的结果:

before GC
weak
after GC
weak

标签:Console,C#,weak,回收,对象,GC,引用
From: https://www.cnblogs.com/johnyang/p/17205466.html

相关文章

  • AC.844 走迷宫
     #include<iostream>#include<queue>#include<utility>//pair容器的头文件#include<cstring>//memsetusingnamespacestd;constintN=1e2+7;intn,m;intg[......
  • 记一次archlinux+dwm的安装
    记一次Archlinux+dwm简单安装联网rfkillunblockalldhcpcdpingwww.baidu.com-n同步时间timedatectlset-ntptrue换源vim/etc/pacman.d/mirrorlistServer=......
  • [CSS] 胶囊按钮与border-radius
    胶囊按钮高度固定以前在写这种形状的按钮的时候,我一般是写了一个固定高度,然后border-radius设置为高度的一半:.pill-button{width:auto;min-width:128px;......
  • db + mysql vs oracle
    smysql与oracle的几点区别序号mysqloracle备注1.组函数用法规则mysql中组函数在select语句中可以随意使用oracle中如果查询语句中有组函数,那其他列名必须是......
  • vscode cn_blog测试
    vscodecn_blog测试1.编辑文本,插入图片2.插入代码print('Hello!cn_blog')vim~/.bashrc......
  • 跟艾文学编程《零基础入门学Python》PyCharm 安装
    作者:艾文,计算机硕士学位,企业内训讲师和金牌面试官,公司资深算法专家,现就职BAT一线大厂。学习目标PyCharm下载PyCharm工具的使用利用PyCharm工具开发第一个应用程序PyChar......
  • ES008-Elasticsearch+hbase整合
    1:设计索引库的settings信息的mappings信息,并把这些配置信息保存到一个配置文件中。1.1viarticles.json{"settings":{"number_of_shards":3,"nu......
  • ES007-Elasticsearch中文分词集成
    1、elasticsearch官方只提供smartcn这个中文分词插件,效果不是很好2、引入分词器前命令行下测试curl'http://localhost:9200/jf/_analyze?pretty=true'-d'{......
  • 浙大版《C语言程序设计(第3版)》题目集 习题5-1 符号函数
    本题要求实现符号函数sign(x)。函数接口定义:intsign(intx);其中​​x​​是用户传入的整型参数。符号函数的定义为:若​​x​​大于0,​​sign(x)​​ = 1;若​​x​​等......
  • 浙大版《C语言程序设计(第3版)》题目集 习题5-1 符号函数
    本题要求实现符号函数sign(x)。函数接口定义:intsign(intx);其中​​x​​是用户传入的整型参数。符号函数的定义为:若​​x​​大于0,​​sign(x)​​ = 1;若​​x​​等......