1、关于字符串操作对应用程序性能的影响

字符串相等性检查是应用程序常见的操作,于此同时,这也是一种严重损害性能的操作.执行序号(字符串的二进制)相等行检查时,CLR会进行以下操作:

1、判断字符串的长度是否相等,不相等,比较结果直接返回false,如果相等,继续下一步操作

2、比较字符串的长度相等,CLR会比较每个单独的字符才能最终确定。而执行对语言文化敏感的比较时,CLR必须比较所   有单独的字符,因为字符串即使长度不同也可能相等.

2、字符串留用  一  减少复制相同字符串实例对内存的消耗

因为字符串的不可变性,如果应用程序经常对字符串进行区分大小写的序号比较,这个时候如果你知道有许多字符串会有相同的值,那么就可以利用CLR的"字符串留用"机制来提升应用程序的性能.

原理:只保存相同字符串的一个实例来提升内存的利用率。将相同的字符串变量引用都指向一个字符串对象.

3、CLR实现字符串留用的过程

CLR初始化时会创建一个内部哈希表.在这个表中,键(key)是字符串,而值(value)是对托管堆中的String对象的引用.这个过程类似与四、CLR执行程序集中代码和IL代码简介 CLR第一次执行一个方法的过程类似,它会初始化一个内部结构,生成一系列的地址,地址指向JITComliler函数,该函数会将代码转成CPU指令等操作,并返回结果给调用的C#方法.

注:该哈希表最开始是空的.

String类提供了两个方法便于你访问这个内部哈希表:

(1)、Intern方法用于获取一个String,获得它的哈希码,并在哈希表中检查是否有相匹配的,如果存在完全相同的字符串,就返回对现有String对象的应用.如果不存在全完相同的字符串,就创建字符串的副本.将副本添加到内部哈希表中,返回对该副本的引用.如果应用程序不再保持对原始String对象的引用,这时垃圾回收器就会介入,将字符串的内存强行释放掉.

注:垃圾回收器不会释放内部哈希表引用的字符串,因为哈希表正在容纳对它们的引用.除非卸载AppDomain或进程终止,否则其内部哈希表应用的String对象不能被释放.

(2)IsInterned方法也获取一个String,并在内部哈西表中查找它.如果哈西表中有匹配的字符串,IsInterned方法就返回对这个留用字符串对象的应用.但如果没有,IsInterned就返回null,不会将字符串添加到哈希表中.

4、CLR默认留用程序集元数据中的字面值字符串

程序集加载时,CLR默认留用程序集元数据中的描述的所有字面值字符串,大微软知道这个过程可能因为额外的哈希表查找而显著影响性能,所以现在可以禁用此功能.通过对程序集用System.RunTime.ComiplerServices.CompilationRelaxationsAttribute进行了标记,并指定了System.RunTime.ComiplerServices.CompilationRelaxations.NoStringIntering标志值.那么根据ECMA规范,CLR可能选择不留用指定程序集的元数据定义的所有字符串.为了提升性能,C#编译器在编译程序集是总是指定上述连个特性和标志.

5、CLR的4.5班版本及以上选择忽略4中的特性和标志,及显示留用指定字符串

由于CLR4.5及以上选择忽略4中的特性,所以程序集加载到AppDomain中时,CLR会对该程序集中元数据中所描述的所有字面值字符串.代码如下:

String str = "xiaochao";
String str1 = "xiaochao";
Console.WriteLine(ReferenceEquals(str,str1));//输出:True

注:程序集加载到AppDomian中时,CLR对程序集中的元数据中的字面值字符串进行了留用,所以导致了"xiaochao"被留用,结果str和str1引用了堆中的同一个"xiaochao"字符串,但是我们的代码不能依赖这一行为,因为未来的CLR版本可能会重视这些特性和标志,到时候将不会对程序集元数据中的字面值字符串不进行留用.下面的代码将显示留用字符串,代码如下:

//去内部哈希表中检查是否有xiaochao字符串,有的话返回该字符串的引用,反之,创建该字符串的副本,返回该副本的引用.
str = String.Intern(str);
//去内部哈希表中检查是否有xiaochao字符串,发现有xiaochao字符串,返回它的引用
str1 = String.Intern(str1);
Console.WriteLine(ReferenceEquals(str, str1));//输出:True

6、字符串池

编译源代码时,编译器必须处理每个字面值字符串,并在托管模块中的元数据中嵌入.同一个字符串在源代码中多次出现,如果每次都去内存中重复开辟空间,不仅浪费内存,而且把它们嵌入元数据会使生成的文件无谓的增大.

为了解决这个问题,许多编译器(包括C#编译器)只在模块的元数据中只将字面值字符串至写入一次,CLR默认留用程序集元数据中的字面值字符串。引用改字符串的所有代码都被修改成引用元数据中的同一个字符串.编译器将单个字符串的多个实例合并成一个实例,能显著减少模块的大小.C/C++编译器多年来一直采用这个技术,这个技术被称为"字符串池".

转载于:https://www.cnblogs.com/GreenLeaves/p/9095037.html

字符串留用与字符串池相关推荐

  1. Java · 认识 String 类(上)· 创建字符串 · 字符串比较相等 · 字符串常量池 · 字符串不可变 · 字符字节与字符串

    目录 一.创建字符串 二.字符串比较相等 三.字符串常量池 3.1 直接赋值的内存情况 3.2 采用构造方法的内存情况 四.理解字符串不可变 五.字符.字节与字符串 5.1 字符与字符串 5.2 字节 ...

  2. java 字符串驻留_JAVA 字符串驻留池

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

  3. java 创建string对象机制 字符串缓冲池 字符串拼接机制 字符串中intern()方法...

    字符串常量池:字符串常量池在方法区中 为了优化空间,为了减少在JVM中创建的字符串的数量,字符串类维护了一个字符串池,每当代码创建字符串常量时,JVM会首先检查字符串常量池.如果字符串已经存在池中,就 ...

  4. java字符串底层实现_「JAVA」细述合理创建字符串,分析字符串的底层存储,你不该错过...

    Java基础之字符串操作--String 字符串 什么是字符串?如果直接按照字面意思来理解就是多个字符连接起来组合成的字符序列.为了更好的理解以上的理论,我们先来解释下字符序列,字符序列:把多个字符按 ...

  5. java字符串定义_java字符串基本概念

    java字符串基本概念 那随意了 • 2020 年 02 月 23 日 字符串字符串本质是一个char类型的数组 private final char value[] //底层的实现代码 不可变字符串 ...

  6. android string拼接字符串_「JAVA」细述合理创建字符串,分析字符串的底层存储,你不该错过...

    Java基础之字符串操作--String 字符串 什么是字符串?如果直接按照字面意思来理解就是多个字符连接起来组合成的字符序列.为了更好的理解以上的理论,我们先来解释下字符序列,字符序列:把多个字符按 ...

  7. delphi 字符串占用空间_字符串在Python内部是如何省内存的

    起步 Python3 起,str 就采用了 Unicode 编码(注意这里并不是 utf8 编码,尽管 .py 文件默认编码是 utf8 ). 每个标准 Unicode 字符占用 4 个字节.这对于内 ...

  8. java 字符串函数_Java字符串函数– 25+必须知道方法

    java 字符串函数 Java字符串函数 (Java String Functions) Java String class has a lot of functions to manipulate ...

  9. java 字符串面试_Java字符串面试问答

    java 字符串面试 String is one of the most widely used Java Class. Here I am listing some important Java S ...

最新文章

  1. mfc 开启指定服务器,用MFC实现消息的发送和接收(含服务器)
  2. git查看linux内核log,linux查看用户、内核、CPU信息
  3. NDK编译生成so文件
  4. DOS - COPY
  5. xieshiran:使用 R 语言开发评分卡模型
  6. let const缓存for循环的中间变量
  7. 阿里巴巴制定了这 16 条
  8. rootfs 制作ubuntu_为n1制作aarcm64/arm64 ubuntu rootfs系统
  9. DATEDIFF() 函数返回两个日期之间的天数
  10. Solaris 网络 配置
  11. Lucene 原理分析之-全文检索的一般过程-笔记
  12. 5.8Ghz微波雷达感应技术,智能雷达传感器,人体感应技术方案
  13. 代码实现抖音时钟罗盘
  14. 神经网络测试样本的选择,如何测试神经网络模型
  15. 台式电脑的计算机界面,台式机怎么进bios界面 台式电脑设置bios的方法
  16. Django 入门:tests.py
  17. excel 常用技巧
  18. linux cpu降频怎么设置,Android系统修改CPU降频温度阈值、修改CPU关内核温度阈值的方法...
  19. delphi 注册列表的学习
  20. CrossTalk典型串扰影响及其处理方法分析

热门文章

  1. 程序员的浪漫,你值得拥有!
  2. 阿里“火拼”拼多多,要“1元”抢占下沉市场
  3. 一场B站服务端开发面试之旅
  4. 【转载】Java异常控制机制和异常处理原则
  5. Confluence 6 配置管理员会话安全的备注
  6. vue开发知识点总结
  7. [Node.js] 2、利用node-git-server快速搭建git服务器
  8. Thinkpad W520 完美安装Ubuntu14.04LTS
  9. 前端小项目:使用canvas绘画哆啦A梦
  10. 简单例子解释invalidate(), requestLayout() (常用还是需要知道的)