您的位置:首页 > 其它

关于String存储机制的理解

2012-06-01 16:46 399 查看


一.字符串存储机制
.NET应用程序开始运行CLR会为该应用程序创建一个默认的托管堆,应用程序的所有的内存分配都在该堆上进行
CLR通过维护一个表来存放字符串,该表称为"暂存池",该容器的key是字符串内容,value是字符串在托管堆上的内存地址.

它包含程序中以编程方式声明或创建的每个唯一的字符串的一个引用。因此,具有特定值的字符串的实例在系统中只有一个。
例如,如果将同一字符串分配给几个变量,运行时就会从暂存池中检索对该字符串的相同引用,并将它分配给各个变量。

引用类型的值存储在托管堆里。


二. 字符串创建解析

情况1.

String s1="hello"; //注意:这里s1赋值字符串常量
s1="world"; //注意:这里s1赋值字符串常量

字符串横定性是指一个字符串一经创建,就不可改变。那么也就是说当我们改变s1值的时候,便会在托管堆上重新分配一块新的内存空间("world"),s1便指向这块新的内存空间,而不会影响到原有的内存地址上所存储的值。原有的内存空间("hello"),如果长时间没有其他String变量来指向它,很有可能会被回收或定期清理。
如图所示:



情况2.

string s1="hello"; //注意:这里s1赋值字符串常量
string s2="hello"; //注意:这里s2赋值字符串常量

s1把对象引用复制给了s2,s2指向s1的内存地址。可以说s1和s2是同一个对象,就像
User u2;
User u1=new User();
u2=u1;
如图所示:



情况4.

string s1="hello"; //注意:这里s1赋值字符串常量
string s2="world"; //注意:这里s2赋值字符串常量

s1和s2各分配新的内存空间,如下图所示:



三.字符串连接

string s1 ="a";和string s2 = "a" + "b";各进行了几次内存分配?
两段代码所分配内存的次数是一样的。在所有的字符串都是字符串常量时,编译器会在编译时将它们连接成一个字符串。也就是说在碰到诸如"a"+"b"这样的代码时,编译器会自动合并为"ab"
但如果是:string s1 = "hello";strings2 = "helloworld";string s3=s1+"world";就不一样了。注意//这里s3是字符串变量s1和常量"world"连接而成的。
测试1:
Console.WriteLine(Object.ReferenceEquals(s2,s3)) -------False
原因是s3是动态生成的字符串,这样的字符串是不会添加到暂存池中进行维护到的。具体存储在那里要进一步研究??

测试2:
Console.WriteLine(Object.ReferenceEquals(s2,s1)) -------False
s1 和 s2 是两个不同的对象(内存地址不同);

测试3:

s3 = String.Intern(s3);
Console.WriteLine(Object.ReferenceEquals(s2,s3)) -------True
Intern 方法使用暂存池来搜索与 s3 值相等的字符串。 如果存在这样的字符串,则返回暂存池中它的引用。 如果不存在,则向暂存池添加对 s3 的引用,然后返回该引用。
由于存在与s3 具有相同值的字符串s2, 将s2 引用赋给 s3。而 s2 和s3 内存引用是相等,因为它们引用同一字符串。

这篇文章是否让你对字符串有了更深刻的了解了呢,也许里面还有些不足之处,就算是抛砖引玉了吧

,希望大家多多提问和发表意见,洗耳恭听。。。。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: