• 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 { getprivate 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 }

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

  • 相关阅读:
    线程正常终止pthread_exit,pthread_join,pthread_kill,pthread_cancel,sigwait,sigaddset
    线程的创建,pthread_create,pthread_self,pthread_once
    线程和进程的关系
    改变进程的优先级,nice,getpriority,setpriority
    setuid和setgid
    等待进程结束wait,waitpid
    执行新程序以及环境变量
    进程退出exit、_exit、abort
    VBA 判断单元格是否为公式,可用于数组
    ADODB 调用存储过程
  • 原文地址:https://www.cnblogs.com/wf225/p/1965236.html
Copyright © 2020-2023  润新知