C# 字符串驻留机制

目录
一、具有相同字符序列的String对象不会重复创建
二、字符串驻留机制同样于string literal + string literal的运算
三、字符串驻留机智不适合variable + string literal形式
四、调用string.Intern可以对运算结果进行强制驻留
五、驻留的字符串不能被GC回收
六、字符串驻留是基于整个进程的

 

  1  public   class  StringInMemory
  2  {
  3       ///   <summary>
  4       ///  1. 具有相同字符序列的String对象不会重复创建
  5       ///   </summary>
  6       public   static   void  BuildString()
  7      {
  8          var str1  =   " ABCDEFG " ;
  9          var str2  =   " ABCDEFG " ;
 10          var str3  =   " 1234567 " ;
 11          var str4  =   " 1234567 " ;
 12 
 13          GC.Collect();
 14          System.Diagnostics.Debug.Assert( string .ReferenceEquals(str1, str2));
 15      }
 16 
 17       ///   <summary>
 18       ///  2. 字符串驻留机制同样于string literal + string literal的运算
 19       ///   </summary>
 20       public   static   void  BuildString2()
 21      {
 22          var str1  =   " ABCDEFG " ;
 23          var str2  =   " ABCD "   +   " EFG " ;
 24          var str3  =   " 1234567 " ;
 25          var str4  =   " 1234 "   +   " 567 " ;
 26 
 27          System.Diagnostics.Debug.Assert( string .ReferenceEquals(str1, str2));
 28      }
 29 
 30       ///   <summary>
 31       ///  3. 字符串驻留机智不适合Variable + string literal形式
 32       ///   </summary>
 33       public   static   void  BuildString3()
 34      {
 35           /// 无论是变量和一个字符串常量相加,还是两个字符串常量相加,运算的结果“ABCDEFG1234678”
 36           /// 并没有被驻留下来(实际上此时它已经是一个垃圾对象,GC可以对其进行回收)。
 37          var str1  =   " ABCDEFG " ;
 38          var str2  =   " 1234567 " ;
 39          var str3  =   " ABCDEFG "   +  str2;
 40          var str4  =  str1  +   " 1234567 " ;
 41          var str5  =  str1  +  str2;
 42 
 43          System.Diagnostics.Debug.Assert( string .ReferenceEquals(str3, str4));
 44      }
 45 
 46       ///   <summary>
 47       ///  4. 调用string.Intern可以对运算结果进行强制驻留
 48       ///   </summary>
 49       public   static   void  BuildString4()
 50      {
 51           /// 虽然涉及到变量的字符串连接运算结果不会被驻留,但是我们可以通过调用string.Intern方法对其进行强制驻留,
 52           /// 该方法会迫使传入传入参数表示的字符串被保存到驻留池中
 53          var str1  =   " ABCDEFG " ;
 54          var str2  =   " 1234567 " ;
 55          var str3  =   string .Intern( " ABCDEFG "   +  str2);
 56          var str4  =   string .Intern(str1  +   " 1234567 " );
 57 
 58          System.Diagnostics.Debug.Assert( string .ReferenceEquals(str3, str4));
 59      }
 60 
 61       ///   <summary>
 62       ///  5. 驻留的字符串不能被GC回收
 63       ///   </summary>
 64       public   static   void  BuildString5()
 65      {
 66          BuildString();
 67 
 68          GC.Collect();
 69          GC.Collect();
 70      }
 71 
 72       ///   <summary>
 73       ///  6. 驻留的字符串是基于整个进程范围的,而不是基于当前AppDomain。
 74       ///   </summary>
 75       public   static   void  BuildString6()
 76      {
 77          AppDomainContext.CreateDomainContext( " Domain A " ).Invoke < Foo > (foo  =>  foo.BuildString());
 78          AppDomainContext.CreateDomainContext( " Domain B " ).Invoke < Foo > (foo  =>  foo.BuildString());
 79          AppDomainContext.CreateDomainContext( " Domain C " ).Invoke < Foo > (foo  =>  foo.BuildString());           
 80      }
 81 
 82       public   class  AppDomainContext
 83      {
 84           public  AppDomain AppDomain {  get private   set ; }
 85           private  AppDomainContext( string  friendlyName)
 86          {
 87               this .AppDomain  =  AppDomain.CreateDomain(friendlyName);
 88          }
 89 
 90           public   static  AppDomainContext CreateDomainContext( string  friendlyName)
 91          {
 92               return   new  AppDomainContext(friendlyName);
 93          }
 94 
 95           public   void  Invoke < T > (Action < T >  action)
 96          {
 97              T instance  =  (T) this .AppDomain.CreateInstanceAndUnwrap( typeof (T).Assembly.FullName,  typeof (T).FullName);
 98              action(instance);
 99          }
100      }
101 
102       public   class  Foo : MarshalByRefObject
103      {
104           public   void  BuildString()
105          {
106              var str1  =   " ABCDEFG " ;
107              var str2  =   " ABCDEFG " ;
108              var str3  =   " 1234567 " ;
109              var str4  =   " 1234567 " ;
110          }
111      }
112  }

原文:通过内存分析工具来证明字符串驻留机制

你可能感兴趣的:(C# 字符串驻留机制)