最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

一文詳解C#字符串不可變性和字符串駐留池

 更新時間:2026年05月08日 09:55:43   作者:工程師007  
文章主要講述了C#中字符串的不可變性、字符串駐留池的概念以及二者之間的關(guān)系,詳細解釋了不可變字符串的特點及其帶來的問題,并介紹了字符串駐留池的原理、分類和使用場景,最后,文章總結(jié)了不可變性與駐留池的關(guān)系以及字符串操作的優(yōu)化建議,需要的朋友可以參考下

一、字符串不可變性(String Immutability)

1. 定義

C# 中 string 是不可變(只讀)引用類型一旦字符串在內(nèi)存中創(chuàng)建,就永遠不能被修改,任何 “修改” 操作都不會改動原字符串,而是新建一個字符串。

2. 為什么不可變

  1. 線程安全:只讀,多線程同時讀不用加鎖
  2. 支持駐留池:相同文本復(fù)用同一塊內(nèi)存,不怕被篡改
  3. 簡化 GC、緩存、哈希設(shè)計
string s = "abc";
s.ToUpper();
Console.WriteLine(s); // 還是 abc,原字符串沒變

ToUpper() 沒有改原 s,而是返回了一個全新字符串對象

再看拼接:

string a = "123";
a += "456";

底層:

  • 不修改原 "123"
  • 重新分配內(nèi)存,創(chuàng)建 "123456" 新字符串
  • a 引用指向新對象,舊對象等待 GC

3. 不可變帶來的問題

頻繁拼接字符串(循環(huán)里 +=)會不斷生成新字符串、大量創(chuàng)建臨時對象、觸發(fā) GC。解決方案:StringBuilderStringBuilder可變的,內(nèi)部維護字符緩沖區(qū),原地修改,不頻繁新建對象。

二、字符串駐留池(String Intern Pool)

1. 是什么

CLR 維護的一個全局字符串緩存池,目的:復(fù)用相同內(nèi)容的字符串實例,節(jié)約內(nèi)存、減少重復(fù)分配。

核心規(guī)則:內(nèi)容相同的字符串,在駐留池中只存一份,多個引用指向同一個內(nèi)存地址。

2. 駐留池分類

  1. 編譯期駐留(常量字符串)
  2. 運行期手動駐留(string.Intern()

三、編譯期駐留

原理

代碼里雙引號直接寫的字面量字符串,編譯時 CLR 會:

示例證明地址相同

string s1 = "hello";
string s2 = "hello";

// 值相等
Console.WriteLine(s1 == s2);      
// 引用地址也相等 同一個對象
Console.WriteLine(object.ReferenceEquals(s1, s2)); 

輸出都是 True?? s1、s2 指向堆上同一個字符串實例。

不進入駐留池的情況

運行時動態(tài)拼接、new 出來的字符串,默認不駐留

string s1 = "hello";
string s2 = "hel" + "lo";   // 編譯器優(yōu)化,還是字面量,會駐留
string s3 = new string("hello".ToCharArray()); 

Console.WriteLine(object.ReferenceEquals(s1, s3)); // False

s3 是運行時構(gòu)造,不在駐留池,是新對象。

四、運行期手動駐留:string.Intern ()

用法

string s3 = new string("hello".ToCharArray());
string internStr = string.Intern(s3);

// 現(xiàn)在和 s1 指向同一個駐留池實例
Console.WriteLine(object.ReferenceEquals(s1, internStr)); // True

Intern 原理

  1. 拿字符串內(nèi)容去駐留池查找
  2. 找到:返回池里已有實例引用
  3. 沒找到:把當(dāng)前字符串加入駐留池,返回引用

適用場景:大量重復(fù)動態(tài)字符串(如日志、解析文本),手動駐留省內(nèi)存。

五、駐留池存在哪里

  • .NET Framework:進程級全局駐留池,程序運行一直存在
  • .NET Core/.NET 5+:每個 AppDomain 獨立駐留池駐留池里的字符串生命周期很長,不容易被 GC 回收。

六、不可變性 + 駐留池 關(guān)聯(lián)關(guān)系

  • 正因為字符串不可變,才敢做駐留池
  • 如果字符串可修改,一個引用改了內(nèi)容,所有指向它的變量都會被篡改,完全亂套
  • 不可變 + 駐留池 = 安全復(fù)用內(nèi)存

七、總結(jié)

  • 字符串不可改,一改建新串
  • 字面量進駐留池,同內(nèi)容共用一塊內(nèi)存
  • 動態(tài)拼接默認不駐留,地址不同
  • string.Intern 手動入池,復(fù)用實例省內(nèi)存
  • 頻繁拼接用 StringBuilder,避免大量生成新字符串

以上就是一文詳解C#字符串不可變性和字符串駐留池的詳細內(nèi)容,更多關(guān)于C#字符串不可變性和駐留池的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評論

邵阳县| 银川市| 肃宁县| 彰化市| 阳信县| 沙河市| 钦州市| 政和县| 桃源县| 汾阳市| 二连浩特市| 张北县| 临汾市| 墨竹工卡县| 和林格尔县| 上杭县| 彭阳县| 九龙城区| 甘孜县| 石门县| 凌云县| 合江县| 清丰县| 乌苏市| 仁怀市| 安国市| 海阳市| 阜康市| 个旧市| 申扎县| 始兴县| 岳阳市| 庆元县| 兴安县| 普兰县| 威信县| 青冈县| 运城市| 屯门区| 旺苍县| 永泰县|