转自:http://www.cnblogs.com/Charles2008/archive/2009/04/12/1434115.html

MSDN概念:公共语言运行库通过维护一个表来存放字符串,该表称为拘留池,它包含程序中以编程方式声明或创建的每个唯一的字符串的一个引用。因此,具有特定值的字符串的实例在系统中只有一个。

上面的概念不好理解,我们还是从基础说起:

一、众所周知,C#中的string是一个引用类型,String对象存放在堆上,而不是在堆栈上的,因此,当把一个字符串变量赋给另一个字符串时,会得到内存中同一个字符串的2个引用。但是为什么我们修改一个字符串的值,而另一个字符串的值不受影响呢?原来当我们把一个字符串的值赋给另一个字符串时候,就会创建一个全新的String对象,就是说是分别指向堆中2个完全不同的地址空间。下面是一个简单例子:

static void Main(string[] args)
        {
string s1 = "Charles";
string s2 = s1; //注意此时会创建一个新对象
            Console.WriteLine("s1=" + s1);
           Console.WriteLine("s2=" + s2);
           s1 = "Charles Chen Change";
           Console.WriteLine("s1=" + s1);
           Console.WriteLine("s2=" + s2);  
        }

结果是:

s1=Charles
s2=Charles
s1=Charles Chen Change
s2=Charles

也就是说,改变s1的值并没有改变s2的值,这实际上是和引用类型是矛盾的。其实当S1="Charles"时候,就在堆上分配了一个String对象,在S2=S1时候,引用也指向这个引用,但是当S1的值发生变化的时候,而不是替换原来的值,实际上是在堆上新分配一个内存空间,S2的值还是指向原来的对象,所以塔的值没有发生变化。

二、然后我们看看下面的代码块:

string str1 = "CharlesChen";
string str2 = "CharlesChen";

当我们调用System.Object.Equals(str1,str2)时候,返回值是True,根据对上面的理解,按道理说是应该返回为false,str1和str2应该指向不同的内存空间才对。怎么会返回为true呢?这里就引入了"字符串驻留技术"。

其实这里CLR使用了字符串驻留技术,对于string str1="CharlesChen";string str2="CharlesChen";

当CLR初始化时,会创建一个内部的散列表(Hash表),其中的键位字符串,值为指向托管堆中字符串的引用。刚开始,散列表为空,JIT编译器编译方法时,会在散列表中查找每一个文本字符串常量(这里是"CharlesChen"),首先会查找"CharlesChen",并且因为没找到,编译器会在托管堆中构造一个全新的指向"CharlesChen"的对象引用,然后将"abc"字符串和执行该对象的引用添加到散列表中去。

当string str2="CharlesChen"时候,由于前面已经在散列表中加了该"CharlesChen"字符串,所以编译器不会执行任何分配内存空间的操作。首先编译器会在内部的散列表中查找"CharlesChen",并且会找到,这样指向先前创建的String对象的引用就会被找到,并且这里Str2就指向找到的那个引用。因此Str1和Str2就指向了内存中同一个地址的引用。所以System.Ojbect.Equals(str1,str2)就返回为true了。

相关资料:

http://www.cnblogs.com/coderlee/archive/2008/01/02/1023316.html 一个字符串驻留技术的demo,加深对它的理解.

C#中字符串驻留技术的更多相关文章

  1. C#中字符串 "驻留"与Lock(转载)

    class TestWorker 2 {         3     public void DoMultiThreadedWork(object someParameter) 4     { 5   ...

  2. Java中的字符串驻留

    转自:http://www.cdtarena.com/javapx/201307/9088.html 最近在工作的时候,一句再正常不过的代码String a = “hello” + “world”;被 ...

  3. Python中字符串的intern机制

    intern机制: 字符串类型作为Python中最常用的数据类型之一,Python解释器为了提高字符串使用的效率和使用性能,做了很多优化,例如:Python解释器中使用了 intern(字符串驻留)的 ...

  4. [你必须知道的.NET]第二十二回:字符串驻留(上)---带着问题思考

    发布日期:2008.8.27 作者:Anytao © 2008 Anytao.com ,Anytao原创作品,转贴请注明作者和出处. 说在,开篇之前 走钢丝的人,在刺激中体验快感.带着问题思考,在问题 ...

  5. 深入 Python 解释器源码,我终于搞明白了字符串驻留的原理!

    英文:https://arpitbhayani.me/blogs/string-interning 作者:arpit 译者:豌豆花下猫("Python猫"公众号作者) 声明:本翻译 ...

  6. 字符串混淆技术应用 设计一个字符串混淆程序 可混淆.NET程序集中的字符串

    关于字符串的研究,目前已经有两篇. 原理篇:字符串混淆技术在.NET程序保护中的应用及如何解密被混淆的字符串  实践篇:字符串反混淆实战 Dotfuscator 4.9 字符串加密技术应对策略 今天来 ...

  7. 字符串反混淆实战 Dotfuscator 4.9 字符串加密技术应对策略

    因为手头需要使用一个第三方类库,网络上又找不到它的可用的版本,于是只好自己动手.这个类库使用了Dotfuscator 加密,用.NET Reflector加载程序集, 看到的字符串是乱码,如下面的代码 ...

  8. JAVA 字符串驻留池

    一切从String str = new String("abc")说起...    这行代码形式上很简单,其实很复杂.有一个常见的Java笔试题就是问上面这行代码创建了几个Stri ...

  9. .net中对象序列化技术浅谈

    .net中对象序列化技术浅谈 2009-03-11 阅读2756评论2 序列化是将对象状态转换为可保持或传输的格式的过程.与序列化相对的是反序列化,它将流转换为对象.这两个过程结合起来,可以轻松地存储 ...

随机推荐

  1. 不可小觑的“alt”

    定义和用法 alt 属性是一个必需的属性,它规定在图像无法显示时的替代文本. 假设由于下列原因用户无法查看图像,alt 属性可以为图像提供替代的信息: 网速太慢 src 属性中的错误 浏览器禁用图像 ...

  2. UITableView详解(转)

    首先.对UITableView进行讲解,下面有对它进行实际的应用 UITableView 显示大型内容的列表 单行,多列 垂直滚动,没有水平滚动 大量的数据集 性能强大,而且普遍存在于iPhone的应 ...

  3. Unite Beijing 2015大型活动

    摘要:2015年,我做的最疯狂的事情:网友见面会—去北京参加Unite Beijing 2015大会. 正文:记得,上次在北京参加大型活动还是2008年前–传统电信行业的巅峰时期:那时移动互联网.An ...

  4. WCF学习笔记 -- 如何用C#开发一个WebService

    假设所有工程的命名空间是demo. 新建一个C#的ClassLibrary(类库)工程. 在工程引用中加入System.ServiceModel引用. 定义接口,你可以删除自动生成的代码,或者直接修改 ...

  5. tinyMCE自定义添加图片插件

    需求: 在富文本编辑器中插入图片,图片来自用户可以自己上传的图片库. 本来可以用比较恶心的方式,也就是直接用tinyMCE自带的插入图片插件来实现.恶心是因为这个图片插件需要用户填入图片的url. 想 ...

  6. Apache 使用密码文件验证用户

    使用文本文件作为密码文件 创建密码文件 需要使用htpasswd.exe文件来创建用户密码文件 语法: htpasswd -c '文件完整路径' 用户名 向一个用户密码文件中添加一个新用户 语法: h ...

  7. Access数据库一种树形结构的实现和子节点查询

    BOOL CManageDataBase::GetDepTreeAllSons( int rootItem ) { CADORecordset Rst(&m_DataBase); BOOL b ...

  8. mysql 恢复备份时出错 Unknown command ‘\”

    今天恢复mysql备份时,出现了Unknown command ‘\”这样的错误,原以为是备份文件出错,重新备份导入时还是出错.研究了一凡是因为编码的问题,解决方案如下: 使用你导出备份时的编码重新导 ...

  9. ubuntu windows 双系统 磁盘乱搞 grub 导致 error:no such partition grub rescue>

    乱搞分区磁盘什么的导致开机和这位仁兄一样:http://zhidao.baidu.com/question/495602654256708364.html?ssid=0&from=100187 ...

  10. jobs

    fg.bg.jobs.&.ctrl + z都是跟系统任务有关的,虽然现在基本上不怎么需要用到这些命令,但学会了也是很实用的一.& 最经常被用到这个用在一个命令的最后,可以把这个命令放到 ...