• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >C#教程 > C#字符串内存分配与驻留池学习分享

C#字符串内存分配与驻留池学习分享

作者: 字体:[增加 减小] 来源:互联网 时间:2017-05-28

通过本文主要向大家介绍了C#字符串内存分配与驻留池学习分享等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

刚开始学习C#的时候,就听说CLR对于String类有一种特别的内存管理机制:有时候,明明声明了两个String类的对象,但是他们偏偏却指向同一个实例。如下:

这里的same会被赋值为true。也就是说s1真的和s2引用了同一个String对象。当然,应该注意到的是s1和s2都被统一赋值为同一个字符串Hello,这才是出现上述情况的原因。

现在我们初步得出结论,当有多个字符串变量包含了同样的字符串实际值时,CLR可能不会为它们重复地分配内存,而是让它们统统指向同一个字符串对象实例。(这里我说了可能,是因为某些情况下,确实也会发生同一个字符串实际值在内存中有多份副本同时存在。请继续往下看。)

我们知道,String类有很多特别的地方,其中之一就是它是不会改变的(immutable)。这说明在我们每次对一个String对象进行操作时(比如说使用Trim,Replace等方法),并不是真的对这个String对象的实例进行修改,而是返回一个新的String对象实例作为操作执行的结果。String对象的实例一经生成,到死都不会被改变了!

基于String类这样的特性,CLR让表示相同的字符串实际值的变量指向同一个String事例,就是完全合理的了。因为利用任何一个对String实例的引用所进行的修改操作都不会切实地影响到该实例的状态,也就不会影响到其他所有指向该实例的引用所表示的字符串实际值。CLR如此管理String类的内存分配,可以优化内存的使用情况,避免内存中包含冗余的数据。

为了实现这个机制,CLR默默地维护了一个叫做驻留池(Intern Pool)的表。这个表记录了所有在代码中使用字面量声明的字符串实例的引用。这说明使用字面量声明的字符串会进入驻留池,而其他方式声明的字符串并不会进入,也就不会自动享受到CLR防止字符串冗余的机制的好处了。这就是我上文提到的某些情况下,确实也会发生同一个字符串实际值在内存中有多份副本同时存在的例子。请看这个例子:


string s1 ="Hello";
string s2 = sb.ToString();

bool same = (object) s1 == (object) s2;
</div>

这时same就不是true了,因为虽然s1,s2表示的是相同的字符串,但是由于s2不是通过字面量声明的,CLR在为sb.ToString()方法的返回值分配内存时,并不会到驻留池中去检查是否有值为Hello的字符串已经存在了,所以自然不会让s2指向驻留池内的对象。
为了让编程者能够强制CLR检查驻留池,以避免冗余的字符串副本,String类的设计者提供了一个名为Intern的类方法。下面是该方法的一个示例:


string s1 ="Hello";
string s2 = String.Intern(sb.ToString());

bool same = (object) s1 == (object) s2;
</div>

好了,same又是true了。Intern方法接受一个字符串作为参数,它会在驻留池中检查是否存在参数所表示的字符串。如果存在,则返回那个驻留池中的字符串的引用;否则向驻留池中加入一个新的表示相同值的字符串,并返回这个字符串的引用。不过要注意的是,就算Intern方法在驻留池中找到了相同值的字符串,也不能让您省却一次字符串内存分配的操作,因为作为参数的字符串已经被分配了一次内存了。而使用Intern方法的好处在于,如果Intern方法在驻留池中找到了相同值的字符串,此时虽然在内存中存在两份该字符串的副本(一份是参数,一份是驻留池中的),但是随着时间的流逝,参数所引用的那个副本会被垃圾回收掉,这样对于该字符串内存中就不存在冗余了。
当您的程序中存在某个方法,可以根据不同的上下文环境创建并返回一个很长的字符串,而在程序运行的过程中它有会经常返回同样的字符串时,您可能就要考虑考虑使用Intern方法来提高内存的利用率了。
不过同样值得注意的是,使用Intern方法让一个字符串存活于驻留池中也有一个副作用:即使已经不存在任何其它引用指向驻留池中的字符串了,这个字符串仍然不一定会被垃圾回收掉。也就是说即使驻留池中的字符串已经没有用处了,它可能也要等到CLR终结时才被销毁。当您使用Intern方法的时候,也应该考虑到这个特殊的行为。

</div>
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

相关文章

  • 2017-05-28C#导出GridView数据到Excel文件类实例
  • 2017-05-28C#和JavaScript实现交互的方法
  • 2017-05-28c#初学简单程序实例代码介绍
  • 2017-05-28C#使用Ado.Net更新和添加数据到Excel表格的方法
  • 2017-05-28C#实现XSL转换的方法
  • 2017-05-28C#实现将商品金额小写转换成大写的方法
  • 2017-05-28C#窗体间通讯处理的几种方法总结
  • 2017-05-28Repeater中添加按钮实现点击按钮获取某一行数据的方法
  • 2017-05-28C#递归算法寻找数组中第K大的数
  • 2017-05-28C#基于NPOI生成具有精确列宽行高的Excel文件的方法

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • asp.net中XML如何做增删改查操作
    • C# 连接SQL数据库的方法及常用连接字符串
    • C#设置开机启动项、取消开机启动项
    • IIS下调用证书出现异常的解决方法 (C#)
    • C#仿密保卡功能的简单实现代码
    • c#根据网址抓取网页截屏生成图片的示例
    • C#中WebClient实现文件下载
    • C#如何给PDF文件添加水印
    • C#中实现一次执行多条带GO的sql语句实例
    • C#获取数组中最大最小值的方法

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有