網站首頁 編程語言 正文
在.NET中,對于相同的字符串,.NET會將它們指向同一個地址,它們是相同的實例。.NET中的字符串并不會更新,當更改一個字符串變量時,由于字符串的不可變性,.NET實際上是新創建一個字符串,而將變量地址指向新創建的字符串地址。
看下面的一個例子:
using System; namespace ConsoleApp2 { class Program { static void Main(string[] args) { string str1 = "hello"; string str2 = "hello"; bool tf = object.ReferenceEquals(str1, str2); Console.WriteLine(tf); Console.ReadKey(); } } }
程序執行結果
從執行結果我們可以得出結論:str1和str2指向同一個內存對象,它們是同一個實例。
在.NET中,CLR默默地維護了一個叫做駐留池(Intern Pool)的表。這個表記錄了所有在代碼中使用字面量聲明的字符串實例的引用。這說明使用字面量聲明的字符串會進入駐留池,而其他方式聲明的字符串則不會進入駐留池,也就不會自動享受到CLR防止字符串冗余的機制的好處了。
看下面一個例子
using System; using System.Text; namespace ConsoleApp2 { class Program { static void Main(string[] args) { StringBuilder sb = new StringBuilder(); sb.Append("he").Append("llo"); string str1 = "hello"; string str2 = sb.ToString(); bool tf = Object.ReferenceEquals(str1, str2); Console.WriteLine(tf); bool tf1 = str1 == str2; Console.WriteLine($"str1和str2的內容是否相同:{tf1}"); Console.ReadKey(); } } }
程序執行結果
這里輸出了False。雖然str1和str2是相同的字符串,但是由于str2不是通過字面量的方式聲明的,CLR在為ToString()返回值分配內存時,并不會到駐留池中去檢查是否有值為"hello"的字符串已經存在了,所以也不會讓str2指向駐留池中的對象。
如果希望強制CLR檢查駐留池,以避免冗余的字符串副本,String類的設計者提供了一個名為Intern的類方法。下面是該方法的一個實例
using System; using System.Text; namespace ConsoleApp2 { class Program { static void Main(string[] args) { StringBuilder sb = new StringBuilder(); sb.Append("he").Append("llo"); string str1 = "hello"; // 在這里強制檢查字符串駐留池 string str2 = string.Intern(sb.ToString()); bool tf = Object.ReferenceEquals(str1, str2); // 輸出True,因為檢查駐留池時,發現字符串已經存在 Console.WriteLine(tf); bool tf1 = str1 == str2; Console.WriteLine($"str1和str2的內容是否相同:{tf1}"); Console.ReadKey(); } } }
程序執行結果
Intern方法接受一個字符串作為參數,它會在駐留池中檢查是否已經存在參數所表示的字符串。如果存在,則返回那個駐留池中的字符串的引用;否則向駐留池中加入一個新的表示相同值的字符串,并返回這個字符串的引用。
不過要注意的是,就算Intern方法在駐留池中找到了相同值的字符串,也不能讓您省卻一次字符串內存分配的操作,因為作為參數的字符串已經被分配了一次內存了。使用Intern方法的好處在于,如果Intern方法在駐留池中找到了相同值的字符串,此時雖然在內存中存在兩份該字符串的副本(一份是參數,一份是駐留池中的),但是隨著時間的流逝,參數所引用的那個副本會被垃圾回收掉,這樣對于該字符串內存中就不存在冗余了。
當你的程序中存在某個方法,可以根據不同的上下文環境創建并返回一個很長的字符串,而在程序運行的過程中它會經常返回同樣的字符串時,你可能就要考慮使用Intern方法來提高內存的使用率了。不過同樣值得注意的是,使用Intern方法讓一個字符串存留于駐留池中也有一個副作用:即使已經不存在任何其它引用指向駐留池中的字符串了,這個字符串仍然不一定會被垃圾回收掉。也就是說即使駐留池中的字符串已經沒有用處了,它可能也要等到CLR終結時才被銷毀。當你使用Intern方法的時候,也應該考慮到這個特殊的行為。
原文鏈接:https://www.cnblogs.com/dotnet261010/p/12677901.html
相關推薦
- 2023-04-03 Input系統截斷策略的分析與應用詳解_Android
- 2022-06-12 C語言動態規劃多種背包問題分析講解_C 語言
- 2022-04-12 React工作流程及Error?Boundaries實現過程講解_React
- 2023-12-23 mybatis的selectOne()方法使用記錄
- 2022-09-20 Python?pip超詳細教程之pip的安裝與使用_python
- 2022-07-03 C#并行編程之信號量_C#教程
- 2022-10-24 Numpy?數據處理?ndarray使用詳解_python
- 2023-05-29 tf.nn.conv2d與tf.layers.conv2d的區別及說明_python
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支