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

 更新时间:2022年03月26日 11:54:52   作者:.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字符串驻留池的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • Asp.Net常用函数

    Asp.Net常用函数

    Asp.Net常用函数...
    2007-03-03
  • c#中常用的js语句

    c#中常用的js语句

    有时候在开发中,经常输出一些js与客户端实现交互,虽然说是c#的其实好多js的,需要的朋友可以收藏下。
    2010-04-04
  • ASP.NET Core Razor页面用法介绍

    ASP.NET Core Razor页面用法介绍

    这篇文章介绍了ASP.NET Core Razor页面的用法,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-02-02
  • C#声明方法实例说明

    C#声明方法实例说明

    方法(Method)是一个已命名的语句集。如果以前使用过其他编程语言,如C或Visual Basic等,就可以将方法视为函数或者子程序相似的东西。每个方法都有一个名称和一个主体。方法名应该是一个有意义的标识符,它应描述出方法的用途(如CalculateIncomeTax)。方法主体包含了调用方法时实际执行的语句。你可以为大多数方法提供一些数据来进行处理,并让它返回一些信息(通常是处理结果)。方法是一种基本的、功能强大的编程机制。
    2008-04-04
  • 使用Docker部署ASP.NET Core程序

    使用Docker部署ASP.NET Core程序

    这篇文章介绍了使用Docker部署ASP.NET Core程序的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-03-03
  • ASP.NET2.0+SQL Server2005构建多层应用

    ASP.NET2.0+SQL Server2005构建多层应用

    ASP.NET2.0+SQL Server2005构建多层应用...
    2006-12-12
  • .Net结构型设计模式之适配器模式(Adapter)

    .Net结构型设计模式之适配器模式(Adapter)

    这篇文章介绍了.Net结构型设计模式之适配器模式(Adapter),文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-05-05
  • ASP.NET Core命名空间System.Text.Encodings.Web介绍

    ASP.NET Core命名空间System.Text.Encodings.Web介绍

    这篇文章介绍了ASP.NET Core命名空间System.Text.Encodings.Web,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-01-01
  • Json.Net6.0用法介绍

    Json.Net6.0用法介绍

    这篇文章介绍了Json.Net6.0的用法,对大家的学习或者工作具有一定的参考学习价值。需要的朋友可以收藏下,方便下次浏览观看
    2021-12-12
  • ASP.NET Core中Startup类、Configure()方法及中间件详解

    ASP.NET Core中Startup类、Configure()方法及中间件详解

    本文详细讲解了ASP.NET Core中Startup类、Configure()方法及中间件,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-01-01

最新评论