2016-01-23 54 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