C#中字符串驻留技术
转自: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#中字符串驻留技术的更多相关文章
- C#中字符串 "驻留"与Lock(转载)
class TestWorker 2 { 3 public void DoMultiThreadedWork(object someParameter) 4 { 5 ...
- Java中的字符串驻留
转自:http://www.cdtarena.com/javapx/201307/9088.html 最近在工作的时候,一句再正常不过的代码String a = “hello” + “world”;被 ...
- Python中字符串的intern机制
intern机制: 字符串类型作为Python中最常用的数据类型之一,Python解释器为了提高字符串使用的效率和使用性能,做了很多优化,例如:Python解释器中使用了 intern(字符串驻留)的 ...
- [你必须知道的.NET]第二十二回:字符串驻留(上)---带着问题思考
发布日期:2008.8.27 作者:Anytao © 2008 Anytao.com ,Anytao原创作品,转贴请注明作者和出处. 说在,开篇之前 走钢丝的人,在刺激中体验快感.带着问题思考,在问题 ...
- 深入 Python 解释器源码,我终于搞明白了字符串驻留的原理!
英文:https://arpitbhayani.me/blogs/string-interning 作者:arpit 译者:豌豆花下猫("Python猫"公众号作者) 声明:本翻译 ...
- 字符串混淆技术应用 设计一个字符串混淆程序 可混淆.NET程序集中的字符串
关于字符串的研究,目前已经有两篇. 原理篇:字符串混淆技术在.NET程序保护中的应用及如何解密被混淆的字符串 实践篇:字符串反混淆实战 Dotfuscator 4.9 字符串加密技术应对策略 今天来 ...
- 字符串反混淆实战 Dotfuscator 4.9 字符串加密技术应对策略
因为手头需要使用一个第三方类库,网络上又找不到它的可用的版本,于是只好自己动手.这个类库使用了Dotfuscator 加密,用.NET Reflector加载程序集, 看到的字符串是乱码,如下面的代码 ...
- JAVA 字符串驻留池
一切从String str = new String("abc")说起... 这行代码形式上很简单,其实很复杂.有一个常见的Java笔试题就是问上面这行代码创建了几个Stri ...
- .net中对象序列化技术浅谈
.net中对象序列化技术浅谈 2009-03-11 阅读2756评论2 序列化是将对象状态转换为可保持或传输的格式的过程.与序列化相对的是反序列化,它将流转换为对象.这两个过程结合起来,可以轻松地存储 ...
随机推荐
- html,css所遇问题(一)
html,css所遇问题(一) div中添加背景图片必须设置宽高 例如:下述代码没有设置icon的宽高值,那么网页中也不会显示出背景图片,因为div 里面有内容才会出现背景,没内容又没设置宽高,那di ...
- 在虚拟机中安装Linux
安装CentOS 6.4教程(详细步骤) CentOS是RHEL的克隆版本,功能上是一模一样的,另外重新编译之后还修复了一些后者的bug.主要区别就是CentOS免费,但没有官方的技术支持,而RHEL ...
- Linux 命令行技巧
这是一个linux常见命令的列表.那些有• 标记的条目,你可以直接拷贝到终端上而不需要任何修改,因此你最好开一个终端边读边剪切&拷贝.所有的命令已在Fedora和Ubuntu下做了测试 命令 ...
- C# 数据结构--单链表
什么是单链表 这两天看到很多有关单链表的面试题,对单链表都不知道是啥的我.经过学习和整理来分享一下啥是单链表和单链表的一些基本使用方法.最后看些网上有关单链表的面试题代码实例. 啥是单链表? 单链表是 ...
- [Bootstrap]全局样式(五)
辅助样式 1.情景文本色 .text-muted .text-primary .text-success .text-info .text-warning .text-danger {c ...
- 【转】fread函数和fwrite函数
1.函数功能 用来读写一个数据块. 2.一般调用形式 fread(buffer,size,count,fp); fwrite(buffer,size,count,fp); 3.说明 ( ...
- 为mapcontrol中的图层设置透明度
ILayer pLayer = axMapControl1.get_Layer(); ILayerEffects pLayerEffects = (ILayerEffects)pLayer; pLay ...
- dsu + lca
贴一下使用dsu和lca的代码,dsu的代码很简单,可以马上写出来,但是lca的代码就不熟练了.这里lca的计算还是用了dfs的访问时间标记,我想起来割边, 割点的判断, dfu[u], low[u] ...
- Contiki学习入门之概览
Contiki是专为物联网领域而设计的开源操作系统,适用于联网嵌入式系统和无线传感器网络.由瑞典计算机科学学院的Adam Dunkels团队开发.它有以下几个特点. 1. 网络标准 contiki提供 ...
- vc++字符转换
测试环境: vs2008 开发语言:C++ #include <iostream>#include <windows.h>#include <string> // ...