这里面有一个坑,前面讨论的相同字符串都是在编译期就知道的,但运行时中的相同字符串是否也会进入驻留池呢? 这是一个让人充满好奇的话题,可以试一下,在程序运行时接受IO输入内容hello,看看是否和str1,str2共享引用地址。
public static void Main(string[] args) { var str1 = "nihao"; var str2 = "nihao"; var str3 = Console.ReadLine(); Console.WriteLine("输入完成!"); Console.ReadLine(); } 0:000> !clrstack -l 000000f6d35fee50 00007ff889e7090d *** WARNING: Unable to verify checksum for ConsoleApp2.exe ConsoleApp2.Program.Main(System.String[]) [C:\dream\Csharp\ConsoleApp1\ConsoleApp2\Program.cs @ 33] LOCALS: 0x000000f6d35fee98 = 0x000002cb1a552d48 0x000000f6d35fee90 = 0x000002cb1a552d48 0x000000f6d35fee88 = 0x000002cb1a555f28 0:000> !do 0x000002cb1a555f28 Name: System.String MethodTable: 00007ff8e7a959c0 EEClass: 00007ff8e7a72ec0 Size: 36(0x24) bytes File: C:\WINDOWS\Microsoft.Net\assembly\GAC_64\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll String: nihao Fields: MT Field Offset Type VT Attr Value Name 00007ff8e7a985a0 4000281 8 System.Int32 1 instance 5 m_stringLength 00007ff8e7a96838 4000282 c System.Char 1 instance 6e m_firstChar 00007ff8e7a959c0 4000286 d8 System.String 0 shared static Empty >> Domain:Value 000002cb18ad39f0:NotInit <<从上面内容可以看到,从Console.ReadLine接收到的引用地址是 0x000002cb1a555f28 ,虽然是相同内容,但却没有使用驻留池,这是因为驻留池在JIT静态解析期就已经解析完成了,也就无法享受复用之优,如果还想复用的话,在 Console.ReadLine() 包一层 string.Intern即可,如下所示:
public static void Main(string[] args) { var str1 = "nihao"; var str2 = "nihao"; var str3 = string.Intern(Console.ReadLine()); Console.WriteLine("输入完成!"); Console.ReadLine(); } ConsoleApp2.Program.Main(System.String[]) [C:\dream\Csharp\ConsoleApp1\ConsoleApp2\Program.cs @ 33] LOCALS: 0x0000008fac1fe9c8 = 0x000001ff46582d48 0x0000008fac1fe9c0 = 0x000001ff46582d48 0x0000008fac1fe9b8 = 0x000001ff46582d48可以看到这个时候str1,str2,str3共享一个内存地址 0x000001ff46582d48。
四: 总结驻留池技术是个很