c# - Newtonsoft Json 反序列化器不释放内存

标签 c# memory json.net

我正在使用带有 JsonTextReaderStreamReader 来反序列化一个包含数万个小对象的大型 JSON 文件,及其消耗方式比我认为合理的内存更多(并且用完了)。我正在使用我所理解的推荐模式来读取大文件。

为了说明目的而简化的代码:

using (StreamReader streamReader = new StreamReader(stream))
using (JsonTextReader reader = new JsonTextReader(streamReader))
{
    JToken token;
    while (reader.Read() && reader.TokenType != JsonToken.EndArray)
    {
        token = JToken.Load(reader);
        RawResult result = token.ToObject<RawResult>();
        results.Add(result);
    }
}

VS2015 内存分析器告诉我大部分内存都被 Newtonsoft.Json.Linq.JValue 对象占用,这很奇怪,因为一旦当前标记被转换为 ToObject () 没有理由(就我而言)它不应该被丢弃。

我假设 Newtonsoft 库将迄今为止解析的所有 JSON 保留在内存中。我不需要它来执行此操作,我想如果我可以避免这种情况,我的内存问题就会消失。

可以做什么?

最佳答案

看起来您不需要使用 JTokens 作为中介;您可以直接反序列化到循环内的 RawResult 类。

using (StreamReader streamReader = new StreamReader(stream))
using (JsonTextReader reader = new JsonTextReader(streamReader))
{
    var serializer = new JsonSerializer();
    while (reader.Read() && reader.TokenType != JsonToken.EndArray)
    {
        RawResult result = serializer.Deserialize<RawResult>(reader);
        results.Add(result);
    }
}

另请注意,通过将结果项添加到列表中,您会将它们全部保存在内存中。如果您可以一次处理一个,并将每个结果单独写入您的输出(文件、数据库、网络流等),您也可以通过这种方式节省内存。

        RawResult result = serializer.Deserialize<RawResult>(reader);
        ProcessResult(result);  // process result now instead of adding to a list

关于c# - Newtonsoft Json 反序列化器不释放内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43257398/

相关文章:

c# - 在单个语句中分配多个值

c# - Log4net 和 Windows 服务。我还应该做些什么才能使这项工作

objective-c - 为什么未初始化的变量包含垃圾而不是 ‘nil’ ?

c# - 如何使用无意义的动态键名反序列化根对象?杰森.NET

c# - 如果它是空的 ('' ) 字符串,则忽略属性来自 Json/Api Response C#

c# - 如何在不安装 Microsoft Office 的情况下在 C# 中创建 Excel(.XLS 和 .XLSX)文件?

c# - WCF - 回调接口(interface)可以指定为通用接口(interface)吗?

ios - 大 (UI) 图像内存管理

delphi - Delphi字符串是不可变的吗?

.net - JsonConvert.SerializeObject 与 JsonSerializer.Serialize