当前位置: 代码网 > it编程>编程语言>Asp.net > .NET中的字符串驻留池介绍

.NET中的字符串驻留池介绍

2024年05月18日 Asp.net 我要评论
在.net中,对于相同的字符串,.net会将它们指向同一个地址,它们是相同的实例。.net中的字符串并不会更新,当更改一个字符串变量时,由于字符串的不可变性,.net实际上是新创建一个字符串,而将变量

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

看下面的一个例子:

using system;

namespace consoleapp2
{
    class program
    {
        static void main(string[] args)
        {
            string str1 = "hello";
            string str2 = "hello";
            bool tf = object.referenceequals(str1, str2);
            console.writeline(tf);
            console.readkey();
        }
    }
}

程序执行结果

从执行结果我们可以得出结论:str1和str2指向同一个内存对象,它们是同一个实例。

在.net中,clr默默地维护了一个叫做驻留池(intern pool)的表。这个表记录了所有在代码中使用字面量声明的字符串实例的引用。这说明使用字面量声明的字符串会进入驻留池,而其他方式声明的字符串则不会进入驻留池,也就不会自动享受到clr防止字符串冗余的机制的好处了。

看下面一个例子

using system;
using system.text;

namespace consoleapp2
{
    class program
    {
        static void main(string[] args)
        {

            stringbuilder sb = new stringbuilder();
            sb.append("he").append("llo");
            string str1 = "hello";
            string str2 = sb.tostring();
            bool tf = object.referenceequals(str1, str2);
            console.writeline(tf);
            bool tf1 = str1 == str2;
            console.writeline($"str1和str2的内容是否相同:{tf1}");
            console.readkey();
        }
    }
}

程序执行结果

这里输出了false。虽然str1和str2是相同的字符串,但是由于str2不是通过字面量的方式声明的,clr在为tostring()返回值分配内存时,并不会到驻留池中去检查是否有值为"hello"的字符串已经存在了,所以也不会让str2指向驻留池中的对象。

如果希望强制clr检查驻留池,以避免冗余的字符串副本,string类的设计者提供了一个名为intern的类方法。下面是该方法的一个实例

using system;
using system.text;

namespace consoleapp2
{
    class program
    {
        static void main(string[] args)
        {

            stringbuilder sb = new stringbuilder();
            sb.append("he").append("llo");
            string str1 = "hello";
            // 在这里强制检查字符串驻留池
            string str2 = string.intern(sb.tostring());
            bool tf = object.referenceequals(str1, str2);
            // 输出true,因为检查驻留池时,发现字符串已经存在
            console.writeline(tf);
            bool tf1 = str1 == str2;
            console.writeline($"str1和str2的内容是否相同:{tf1}");
            console.readkey();
        }
    }
}

程序执行结果

intern方法接受一个字符串作为参数,它会在驻留池中检查是否已经存在参数所表示的字符串。如果存在,则返回那个驻留池中的字符串的引用;否则向驻留池中加入一个新的表示相同值的字符串,并返回这个字符串的引用。

不过要注意的是,就算intern方法在驻留池中找到了相同值的字符串,也不能让您省却一次字符串内存分配的操作,因为作为参数的字符串已经被分配了一次内存了。使用intern方法的好处在于,如果intern方法在驻留池中找到了相同值的字符串,此时虽然在内存中存在两份该字符串的副本(一份是参数,一份是驻留池中的),但是随着时间的流逝,参数所引用的那个副本会被垃圾回收掉,这样对于该字符串内存中就不存在冗余了。

当你的程序中存在某个方法,可以根据不同的上下文环境创建并返回一个很长的字符串,而在程序运行的过程中它会经常返回同样的字符串时,你可能就要考虑使用intern方法来提高内存的使用率了。不过同样值得注意的是,使用intern方法让一个字符串存留于驻留池中也有一个副作用:即使已经不存在任何其它引用指向驻留池中的字符串了,这个字符串仍然不一定会被垃圾回收掉。也就是说即使驻留池中的字符串已经没有用处了,它可能也要等到clr终结时才被销毁。当你使用intern方法的时候,也应该考虑到这个特殊的行为。

到此这篇关于.net字符串驻留池的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持代码网。

(0)

相关文章:

  • ASP.NET Core服务生命周期

    ASP.NET Core服务生命周期

    1.前言在configureservices方法中的容器注册每个应用程序的服务,asp.core都可以为每个应用程序提供三种服务生命周期:transient(暂... [阅读全文]
  • ASP.NET MVC中两个配置文件的作用详解

    前言在新建完一个mvc项目之后,你会发现整个整个项目结构中存在有两个web.config文件,如下图所示:这两个配置文件,一个位于项目的根目录下面,一个位于views文件夹下面,这…

    2024年05月18日 编程语言
  • ASP.NET Core中间件

    1.前言整个http request请求跟http response返回结果之间的处理流程是一个请求管道(request pipeline)。而中间件(middleware)则是一…

    2024年05月18日 编程语言
  • ASP.NET MVC项目部署方式介绍

    asp.net mvc编写的程序需要部署到iis上面才能进行访问,部署方式分为两种。一、直接用源代码部署第一种方式可以直接使用源代码进行部署。部署步骤:1、新建网站在iis里面选择…

    2024年05月18日 编程语言
  • ASP.NET Core中的静态文件

    1.前言当我们创建core项目的时候,web根目录下会有个wwwroot文件目录,wwwroot文件目录里面默认有html、css、img、javascript等文件,而这些文件都…

    2024年05月18日 编程语言
  • ASP.NET MVC模式中应用程序结构详解

    在文章中,讲解了一些mvc的概念,并且创建了第一个asp.net mvc项目,这篇文章将讲解asp.net mvc程序中的代码解构,新创建的mvc应用程序解构如下图所示:一、app…

    2024年05月18日 编程语言

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com