默认情况下,CLR会把字符串常量保存在字符串池中。
.NET 2.0引入了CompilationRelaxations.NoStringInterning枚举成员。这个枚举CompilationRelaxationsAttribute属性配合使用可以把程序集标记为“不要求字符串字面量驻留”(marks an assembly as not requiring string-literal interning)。
从字面意思理解,应用[assembly: CompilationRelaxationsAttribute(CompilationRelaxations.NoStringInterning)]这个属性好像没有强制性的意思。也就是说,CLR的JIT可以选择忽略此属性。

我在.NET 4.0和4.6上都测试了。但是,结果是一样的。不管有没有加[assembly: CompilationRelaxationsAttribute(CompilationRelaxations.NoStringInterning)]这个属性,字符串都会驻留在内存中。

MSDN中的String.Internal方法的说明中有一句话“The reason is that the CLR's reference to the interned String object can persist after your application, or even your application domain, terminates.”。根据这句话理解,即使应用程序结束,甚至即使应用程序域终止了,CLR的驻留字符串引用依然存在。

所以有如下两个可能:
1,CLR的JIT忽略了[assembly: CompilationRelaxationsAttribute(CompilationRelaxations.NoStringInterning)]这个属性。
2,应用程序终止了,但是CLR的驻留字符串引用依然存在。

但是,我更换了好几个字符串的值,结果仍旧不变。
所以第二种可能性显然不成立(最起码在我测试的时候不成立)。
所以,应该是CLR的JIT忽略了[assembly: CompilationRelaxationsAttribute(CompilationRelaxations.NoStringInterning)]这个属性。
应用CompilationRelaxations.NoStringInterning对CLR来说不是强制性的。

以下是测试代码:

 [assembly: CompilationRelaxationsAttribute(CompilationRelaxations.NoStringInterning)]
namespace StringInterningTest
{
class Program
{
static void Main(string[] args)
{
string s1 = "unicode";
string s2 = new string(new char[] { 'u', 'n', 'i', 'c', 'o', 'd', 'e' });
string s3 = "unicode"; bool b1 = (object)s1 == (object)s2;
bool b2 = (object)s1 == (object)s3;
}
}
}

测试结果:
n1的值始终为"unicode"。
n2的值始终为null。

如有不正确的地方,希望各位指正!

关于.NET字符串驻留的问题的更多相关文章

  1. JAVA 字符串驻留池

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

  2. .Net字符串驻留池

    在.Net中,对于相同的字符串,.Net会将它们指向同一个地址,它们是相同的实例..Net中的字符串并不会更新,当更改一个字符串变量时,由于字符串的不可变性,.Net实际上是新创建一个字符串,而将变量 ...

  3. C#中字符串驻留技术

    转自:http://www.cnblogs.com/Charles2008/archive/2009/04/12/1434115.html MSDN概念:公共语言运行库通过维护一个表来存放字符串,该表 ...

  4. C# 字符串驻留池

    在.Net中,对于相同的字符串,.Net会将它们指向同一个地址,它们是相同的实例..Net中的字符串并不会更新,当更改一个字符串变量时,由于字符串的不可变性,.Net实际上是新创建一个字符串,而将变量 ...

  5. Java中的字符串驻留

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

  6. python 的字符串驻留机制

    我们都知道python中的引用计数机制,相同对象的引用其实都是指向内存中的同一个位置,这个也叫做“python的字符串驻留机制”.其他的就不多说了,自行研究. 重点!!!!!! python的引用计数 ...

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

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

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

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

  9. String特性之 “字符串驻留池”

    1. 字符串驻留池,就是一块与堆区并行的存放字符串对象的内存区,JVM的驻留池机制规定: 在池中创建一个String对象,第二行会先在池中寻找是否有值与"abc"相同的String ...

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

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

随机推荐

  1. 流式大数据计算实践(2)----Hadoop集群和Zookeeper

    一.前言 1.上一文搭建好了Hadoop单机模式,这一文继续搭建Hadoop集群 二.搭建Hadoop集群 1.根据上文的流程得到两台单机模式的机器,并保证两台单机模式正常启动,记得第二台机器core ...

  2. jdk中的简单并发,需要掌握

    前言 开心一刻 小时候有一次爸爸带我去偷村头别人家的梨子,我上树摘,爸爸在下面放风,正摘着主人来了,爸爸指着我破口大骂:臭小子,赶紧给我滚下来,敢偷吃别人家梨子,看我不打死你.主人家赶紧说:没事没事, ...

  3. python重试库retryiny源码剖析

    上篇博文介绍了常见需要进行请求重试的场景,本篇博文试着剖析有名的python第三方库retrying源码. 在剖析其源码之前,有必要讲一下retrying的用法,方便理解. 安装: pip insta ...

  4. Django 系列博客(四)

    Django 系列博客(四) 前言 本篇博客介绍 django 如何和数据库进行交互并且通过 model 进行数据的增删查改 ORM简介 ORM全称是:Object Relational Mappin ...

  5. zepto 事件分析1($.Event)

    先看一下zepto事件的函数,在这里,zepto是把zepto对象作为一个立即执行函数的参数传进去的. (function($){ ... ... })(Zepto) 在zepto事件函数中,主要为$ ...

  6. WebApi HTTP Put 405 Method not allowed

    总结列表: 1. There is already an open DataReader associated with this Connection which must be closed fi ...

  7. 一个smtp发送错误

    错误返回: Error: need EHLO and AUTH first ! 原因:服务器是smtp.exmail.qq.com,邮箱账号是企业新申请的邮箱账号,邮箱密码需要重新修改. 解决办法:修 ...

  8. [android] xml文件的序列化

    生成xml文件,模拟备份短信,创建短信的业务bean,创建一个domain的包放业务bean,这个业务bean里面,定义成员属性,生成get set方法,生成有参和无参的构造方法. 生成随机数,实例化 ...

  9. Nginx之OCSP stapling配置

    摘要: 正确地配置OCSP stapling, 可以提高HTTPS性能. 什么是OCSP stapling? OCSP的全称是Online Certificate Status Protocol,即在 ...

  10. layui table动态表头 改变表格头部 重新加载表格

    改变头部原理: 删除原来表格, 重新建立DOM元素, 重新加载table,实现表头改变 明白了原理, 我相信大家都能写出来了, table.reload(ID, options)目前好像还不支持con ...