掃二維碼與項目經(jīng)理溝通
我們在微信上24小時期待你的聲音
解答本文疑問/技術(shù)咨詢/運營咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流
本文轉(zhuǎn)載自微信公眾號「精益碼農(nóng)」,作者小碼甲 。轉(zhuǎn)載本文請聯(lián)系精益碼農(nóng)公眾號。

開局兩張圖,內(nèi)容全靠刷。
馬甲哥看到這樣的現(xiàn)象,一開始還是有點懵逼。
這個例子,string是純粹的引用類型,但是在函數(shù)傳值時類似于值傳遞;我之前給前后示例的內(nèi)存變化圖吧:
根因就是大多數(shù)高級語言都把String設(shè)計成不可變的: 由一個字符串池管理字符串面值。
這個我還真的搜索了一下[1]:
總結(jié)起來:
既然pool里面共享字符面值,修改的時候又不能影響到別人,那就只好重新拷貝產(chǎn)生新的字符面值。
一個有意思的現(xiàn)象是:String雖然是引用類型,字符串對比時卻表現(xiàn)的像值類型
- string str1="FooFoo";
- string strFoo="Foo";
- string str2= strFoo + strFoo;
- return str1 == str2; // 返回true
正因為String不可變性 & Pool的機制,頻繁變更字符串,會在池中產(chǎn)生很多臨時的不用的字符串,所以我們有了優(yōu)化的套路:
代表可變的字符串,一旦修改不會嘗試創(chuàng)建新對象,而是動態(tài)擴展內(nèi)存
- var ss = new StringBuilder("Hello ", 100); // 初次字符容量100
- ss.Append("www.cnblogs.com");
- Console.WriteLine(ss.ToString()); // ss打印結(jié)果為:222
Span該出圈了,
Span提供對內(nèi)存連續(xù)區(qū)域的類型安全訪問,該內(nèi)存可以位于堆、堆棧、甚至是非托管內(nèi)存;
與String不可變性相關(guān)的是ReadOnlySpan(值類型), 提供內(nèi)存數(shù)據(jù)的只讀視圖,每次切片不會產(chǎn)生新對象,而是在已存在的連續(xù)空間上創(chuàng)造新的視圖。
- var text = "https://www.cnblogs.com/JulianHuang/p/14817621.html";
- ReadOnlySpan
nameSpan = text.AsSpan(8, 15); - nameSpan = nameSpan.Slice(4,7);
- Console.WriteLine(nameSpan.ToString());
今天從兩張詭異的編程圖聊到了String的不可變性、內(nèi)存分布, 延伸談到了
String不可變性的設(shè)計設(shè)計考量(有先射箭再畫靶的嫌疑??)
針對頻繁修改的String如何做內(nèi)存優(yōu)化
不是自吹,文章內(nèi)容在業(yè)界相當(dāng)硬核(多次被各大佬/CSDN點贊/轉(zhuǎn)載),閱讀和關(guān)注不是目的,更希望得到更多的閱讀反饋,互相促進認知的提升(相當(dāng)真誠??)。
參考資料
[1]這個我還真的搜索了一下: https://www.c-sharpcorner.com/UploadFile/230635/why-string-are-immutable-in-dotnet/

我們在微信上24小時期待你的聲音
解答本文疑問/技術(shù)咨詢/運營咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流