2016-01-23 58 views
0

我與運行的應用看,所以我試圖更好地利用內存傳遞給它定期相當大的JSON的斑點,如果可能的話,避免一些反序列化時,它上面85KB對象LOH分配。驗證.NET中的瞬態內存分配差異?

我有.NET內存分析器和dotMemory但我對它們是如何被使用,所以我正在尋找一些建議有點生疏。

我的小控制檯應用程序來分析在一個緊密的循環是簡單地執行下面的場景,以獲得一看分配回事。

byte[] incomingMessage = ....; // LOH 
string json = Encoding.UTF8.GetString(incomingMessage); // another LOH 
return JsonSerializer.Deserialize(json); 

VS

byte[] incomingMessage = ....; // LOH 
using (MemoryStream ms = new MemoryStream(incomingMessage)) 
{ 
    using (StreamReader sr = new StreamReader(ms, Encoding.UTF8)) 
    {  
     return JsonSerializer.Deserialize(sr); 
    } 
} 

我的理論是,我將有較少的LOH allocs和分裂所造成的第二代碼片段比第一。

不過,我的問題是,我該如何驗證?上述工具似乎做了一個偉大的工作(尤其是.NET Memory Profiler)比較快照以發現泄漏等,但它不是很明顯我應該尋找我的需求。

+0

如果使用Newtonsoft.Json還有就是解析JSON手動(http://insidethecpu.com/2013/06/19/json-parsing/),像XML解析器流的選項 - 他們解析塊由塊和不加載整個字符串到MEM。 – csharpfolk

回答

0

運行控制檯程序下探查寫在下面,並得到快照時,它會問它。然後看看來自LOH的所有物體。重複第二種方法。

在dotMemory的情況下,打開「所有對象」比「Group by generations」,比LOH對象。

public void Main() 
{ 
    byte[] incomingMessage = ....; // LOH 
    string json = Encoding.UTF8.GetString(incomingMessage); // another LOH 
    var desj = JsonSerializer.Deserialize(json); 
    Console.Writeline("Get snapshot"); 
    Console.ReadLine(); 

    // prevent GC to collect them 
    GC.KeepAlive(incomingMessage); 
    GC.KeepAlive(json); 
    GC.KeepAlive(desj); 
} 
+0

如何知道任何特定JSON庫的流式API不會將整個流讀到最後並在內部創建字符串?我想用這種技術,由於手動的'KeepAlive',我不能確定流式方法是否有更高的內存效率(Ofcourse有一個寫得很好的JSON解析器,它幾乎肯定會是) – jamespconnor