C# 验证.NET中的瞬时内存分配差异?
我正在使用的一个应用程序会定期向它发送相当大的JSON blob,因此我试图更好地利用内存,如果可能的话,避免在反序列化时对85Kb以上的对象进行LOH分配 我有.NET内存分析器和dotMemory,但对如何使用它们有点生疏,所以我正在寻找一些建议 我的小型控制台应用程序to profile只是在一个紧密的循环中执行以下场景,以查看正在进行的分配C# 验证.NET中的瞬时内存分配差异?,c#,.net,json,memory,profiling,C#,.net,Json,Memory,Profiling,我正在使用的一个应用程序会定期向它发送相当大的JSON blob,因此我试图更好地利用内存,如果可能的话,避免在反序列化时对85Kb以上的对象进行LOH分配 我有.NET内存分析器和dotMemory,但对如何使用它们有点生疏,所以我正在寻找一些建议 我的小型控制台应用程序to profile只是在一个紧密的循环中执行以下场景,以查看正在进行的分配 byte[] incomingMessage = ....; // LOH string json = Encoding.UTF8.GetStrin
byte[] incomingMessage = ....; // LOH
string json = Encoding.UTF8.GetString(incomingMessage); // another LOH
return JsonSerializer.Deserialize(json);
vs
我的理论是,与第一个代码片段相比,第二个代码片段导致的LOH ALLOC和碎片更少
然而,我的问题是,我如何验证这一点?上述工具在比较快照以查找漏洞等方面似乎做得很好(特别是.NET内存探查器),但我不清楚我应该寻找什么需要。运行下面在探查器下编写的控制台应用程序,并在它要求时获取快照。然后从LOH查看所有对象。重复第二种方法 如果是dotMemory,请打开“所有对象”而不是“”,打开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);
}
如果您使用Newtonsoft.Json,有一个选项可以手动解析Json(),类似于XML流解析器——它们逐块解析,而不是将整个字符串加载到mem中。我怎么知道任何特定Json库的流API不会将整个流读取到底,并在内部创建字符串?我想使用这种技术,由于手动
KeepAlive
我无法确定流式方法是否更节省内存(当然,如果使用编写良好的JSON解析器,几乎可以肯定)
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);
}