众所周知,在某些情况下,在C#中使用字符串时,CLR会将字符串实际作为优化。
所以我的问题是:
在某些情况下监视内存使用情况时,我可以看到这有点用处。在处理敏感信息时它也可能很有用(尽管我认为SecureString
在许多情况下更为可取)。
据我所知,与字符串实习相关的唯一公共方法是String.Intern(string)
和String.IsInterned(string)
我是出于好奇而不是试图解决一个真正的问题。我意识到,根据字符串实习池做任何逻辑都是个坏主意。
答案 0 :(得分:3)
通过代码查找实习字符串没有用例,所以它的功能没有添加到语言中。
然而,在调试程序时查找内存中的字符串是一个非常常见的用例,并且有工具可以做到这一点。
您需要使用Windows SDK附带的工具WinDbg.exe
。启动它并将其附加到您的程序后,您可以执行命令
.loadby sos clr
这将加载调试.NET应用程序的扩展。完成后,您可以执行命令
!DumpHeap -strings
你可以看到堆中的所有字符串对象。
至于告诉您正在查看的列表中的对象是否被实习,我不完全确定如何。希望如果你问一个关于WinDbg的新问题,以及如何判断一个字符串是否被实习,或者某人可以回答。
答案 1 :(得分:1)
您可以使用基于 ClrMD 的 MemAnalyzer 分析对实习生有意义的字符串和副本。
https://github.com/Alois-xx/MemAnalyzer
C>MemAnalyzer.exe -dstrings -f 50KStringsx64.dmp
Strings(Count) Waste(Bytes) String
500 20,958 String 0
500 20,958 String 1
500 20,958 String 2
500 20,958 String 3
500 20,958 String 4
500 20,958 String 5
Summary
==========================================
Strings 61,330 count
Allocated Size 2,529,742 bytes
Waste Duplicate Strings 2,515,898 bytes
这将为您提供一个指标,表明您拥有多少个字符串,以及哪些字符串可能对实习生有意义。要找出哪个对象引用了您可以添加的特定字符串
-showAddress
显示可能值得实习的每个strng的第一个地址。然后你可以使用Windbg和!GCRoot地址找出哪个对象包含这个字符串,它可以让你知道你需要在哪个类中添加String.Intern调用。
请注意,.NET String.Intern池永远不会释放引用。如果您正在处理具有不同内容的大型数据集,则应使用自己的字典池,以便在卸载当前数据集并加载下一个数据集时释放所有实体字符串。