2017-07-25 28 views
0

衆所周知,在某些情況下,當在C#中使用字符串時,CLR會將字符串interning作爲優化來使用。是否有可能讀取實習生池中的所有字符串?

所以我的問題是:

  • 它可以讀取當前所有的實習生池的字符串?
  • 有沒有辦法讓每個interned字符串的引用計數?
  • 是否可以從單獨的進程空間讀取實習生池?
  • 如果這些都不可能,那麼不允許這些用例的原因是什麼?

在某些情況下,我可以看到這在監視內存使用情況時有點用處。在處理敏感信息時也可能有用(儘管在許多情況下,我認爲SecureString會更可取)。

據我所知,相關的字符串實習唯一的公共方法String.Intern(string)String.IsInterned(string)

我問出於好奇,而不是試圖解決一個真正的問題。我意識到,根據字符串實習生池做任何邏輯將是一個壞主意。

+5

_「不允許使用這些用例的原因是什麼?」因爲[每個功能都以-100分開始](https://blogs.msdn.microsoft.com/ericgu/2004/01/12/minus- 100分/),而團隊則是在做一些實際有用的事情。 – stuartd

+8

「f這些都不可能,不允許這些用例的原因是什麼?」這些不是用例 - 它們是API功能請求*,沒有用例。一個用例可以解釋爲什麼*你想要做這些事情。事後你說你不是在試圖解決一個真正的問題,這表明你沒有*用例。就我個人而言,我並不贊成混淆無用的功能。 –

+0

可能。通過* Microsoft.Diagnostics.Runtime *中的ClrMD API獲取所有對象的列表,並使用* IsInterned *查找所有實例化的字符串。該API還可以提供您需要的其他統計信息。沒有理由這樣做,除非你正在編寫一個調試器。 – IllidanS4

回答

3

通過代碼查找interned字符串沒有用例,所以它的功能沒有添加到語言中。

但是,在調試程序時查找內存中的字符串是一種非常常見的用例,並且有工具可以執行此操作。

您將需要使用Windows SDK附帶的工具WinDbg.exe。啓動它並將其連接到你的程序執行完命令

.loadby sos clr 

,這將在擴展調試.NET應用程序加載。完成之後,您可以執行命令

!DumpHeap -strings 

並且您可以看到堆中的所有字符串對象。

至於說明你正在查看的列表中的對象是否被實習,我不完全確定如何。希望如果你問一個關於WinDbg的新問題,以及如何判斷一個字符串是否被攔截,或者某人可能能夠回答。

1

可以分析串並重復這是有意義的實習生MemAnalyzer這是基於ClrMD

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 

這會給你一個指標,你有多少suplicate字符串有和他們的可能是有意義的實習生。要了解哪些對象引用的特定字符串,您可以添加

-showAddress

顯示,這可能是值得每一個實習的strng第一個地址。然後你可以使用Windbg和!GCRoot地址來找出哪個對象持有這個字符串,這應該給你一個你需要添加String.Intern調用的類的想法。

請注意,.NET String.Intern池永遠不會釋放引用。如果您正在處理具有不同內容的大型數據集,則應使用您自己的字典池,以便在卸載當前數據集並加載下一個字符串時釋放所有實例字符串。

相關問題