C#中的弱引用
弱引用保持的是一個(gè)GC“不可見(jiàn)”的引用,是指弱引用不會(huì)增加對(duì)象的引用計(jì)數(shù),也不會(huì)阻止垃圾回收器對(duì)該對(duì)象進(jìn)行回收。因此,弱引用的目標(biāo)對(duì)象可以被垃圾回收器回收,而弱引用本身不會(huì)對(duì)垃圾回收造成任何影響。
弱引用的原理是,在堆上分配的每個(gè)對(duì)象都有一個(gè)頭部信息,用于存儲(chǔ)對(duì)象的類型信息、對(duì)象的大小等信息。在頭部信息中,還會(huì)有一個(gè)標(biāo)志位用于表示對(duì)象是否被引用。當(dāng)一個(gè)對(duì)象被創(chuàng)建時(shí),該標(biāo)志位為“未引用”。當(dāng)該對(duì)象被弱引用引用時(shí),該標(biāo)志位不會(huì)變?yōu)椤耙岩谩保丛搶?duì)象仍然會(huì)被當(dāng)做未引用的對(duì)象進(jìn)行處理。被強(qiáng)引用后,會(huì)被標(biāo)記為”已引用“,當(dāng)所有的強(qiáng)引用都消失時(shí),該標(biāo)志位會(huì)變?yōu)椤拔匆谩保丛搶?duì)象已經(jīng)沒(méi)有任何強(qiáng)引用指向它,標(biāo)記的工作由GC來(lái)完成。
在垃圾回收時(shí),GC會(huì)根據(jù)標(biāo)記-清除算法對(duì)堆中的對(duì)象進(jìn)行掃描和標(biāo)記,標(biāo)記所有仍然被引用的對(duì)象,然后回收所有未被標(biāo)記的對(duì)象。對(duì)于被弱引用引用的對(duì)象,由于弱引用不會(huì)增加對(duì)象的引用計(jì)數(shù),也不會(huì)阻止垃圾回收器回收該對(duì)象,因此在回收時(shí),該對(duì)象會(huì)被當(dāng)做未被引用的對(duì)象進(jìn)行處理,然后被回收。
總之,弱引用保持的是一個(gè)GC“不可見(jiàn)”的引用,即弱引用不會(huì)影響垃圾回收器對(duì)目標(biāo)對(duì)象的回收,因此可以用于實(shí)現(xiàn)一些場(chǎng)景,例如緩存、對(duì)象池等場(chǎng)景,避免長(zhǎng)時(shí)間占用內(nèi)存或造成內(nèi)存泄漏。
var sb = new StringBuilder("weak");
Console.WriteLine("before GC");
Console.WriteLine(sb);
GC.Collect();//強(qiáng)制垃圾回收
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 方法仍然會(huì)工作,但是它的行為可能會(huì)受到一些影響。
在 debug 模式下,編譯器會(huì)添加額外的調(diào)試信息到代碼中,這些信息可能會(huì)影響垃圾回收器的行為。例如,編譯器可能會(huì)保留一些對(duì)象的引用,以便調(diào)試器可以訪問(wèn)它們,這可能會(huì)導(dǎo)致這些對(duì)象不會(huì)被垃圾回收器回收,直到調(diào)試器不再需要它們?yōu)橹埂R虼耍?dāng)調(diào)用 GC.Collect 方法時(shí),由于存在調(diào)試信息的影響,可能會(huì)出現(xiàn)一些對(duì)象無(wú)法被立即回收的情況。
此外,在 debug 模式下,垃圾回收器的性能也可能會(huì)受到一定的影響,因?yàn)榫幾g器會(huì)添加額外的代碼和調(diào)試信息,導(dǎo)致程序變得更加復(fù)雜和龐大,從而使垃圾回收器需要更長(zhǎng)的時(shí)間來(lái)掃描和回收對(duì)象。
因此,如果需要在 debug 模式下進(jìn)行垃圾回收操作,應(yīng)該仔細(xì)考慮其影響,并進(jìn)行充分的測(cè)試,以確保程序的正確性和性能。同時(shí),還可以考慮使用其他的調(diào)試工具和技術(shù)來(lái)診斷和解決問(wèn)題,避免對(duì)程序的垃圾回收行為產(chǎn)生不必要的影響。
所以,以上代碼在debug模式下,會(huì)有截然不同的結(jié)果:
before GC
weak
after GC
weak
總結(jié)
- 上一篇: Special Binary Strin
- 下一篇: C# 文件系统