转自: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. img与父元素的间隙解决

    近来在做H5页面时,突然发现一个问题,使用一个div包裹一个img,在手机预览时,发现图片与div之间有间隙. 当时第一反应就是,是不是间距没有设置为0,于是预览了下代码: .active img { ...

  2. Jersey(1.19.1) - Building Responses

    Sometimes it is necessary to return additional information in response to a HTTP request. Such infor ...

  3. 【TOMCAT】Tomcat gzip压缩传输数据

    概述 由于我们项目的三维模型文件非常大,为了提高传输速度,在服务端对其做zip压缩处理非常有必要,能够极大的提高传输速度. 配置 首先需要修改web.xml中请求的数据文件的mime类型的mappin ...

  4. selenium Grid(一)

    selenium grid Quick Start selenium-grid是用于设计帮助我们进行分布式测试的工具,其整个结构是由一个hub节点和若干个代理节点组成.hub用来管理各个代理节点的注册 ...

  5. ios开发入门篇(四):UIWebView结合UISearchBar的简单用法

     UIWebView是ios开发中比较常用的一个控件.我们可以用它来浏览网页.打开文档等,今天笔者在这里简单介绍下UIWebView和UISearchBar结合起来的用法,做一个简单的类浏览器. 一: ...

  6. JS判断移动设备最佳方法

    最实用的还是下面这个: 方法一:纯JS判断 使用这方法既简单,又实用,不需要引入jQuery库,把以下代码加入到<head>里即可. <script type=”text/javas ...

  7. Object类型

    Object类型 我们看到的大多数引用类型值都是Object类型的实例,虽然Object类型不具备多少功能,但是在储存和传输数据上的确是不错的选择. 2.对象字面量表示法 调用Object构造函数: ...

  8. Qt自绘窗体

    也许大部分情况下我们不需要自己手动绘制一个窗体,大部分可以通过图片来实现,本篇仅以学习的态度来初略的理解Qt界面的自定义绘制功能.   本篇将实现以下功能: 1.绘制一个椭圆形 2.支持界面的移动操作 ...

  9. Unity3D设置字体颜色大小,用于游戏分数显示设置等,

    最近在学unity3d,慢慢的学会了许多unity的东西,今天记录下unity3d的Label字体大小及颜色的代码,下面是显示游戏中分数的代码,, public static int Score = ...

  10. [CSS]三角形

    CSS盒子模型 当我们把padding和width,height全部设置为0,border设为一个较大的像素时 即:我们需要什么方向的三角形,只需把其余的三角形背景色设置为transparent: