Newtonsoft.Json - 反序列化大对象时出现内存不足异常

9

我在反序列化一个约1GB的JSON文件时遇到了问题。当我运行以下代码时,会抛出内存不足异常:

using (FileStream sr = new FileStream("myFile.json", FileMode.Open, FileAccess.Read))
{
  using (StreamReader reader = new StreamReader(sr))
  {
    using (JsonReader jsReader = new JsonTextReader(reader))
    {
      JsonSerializer serializer = new JsonSerializer();
      dataObject = serializer.Deserialize<T>(jsReader);
    }
  }
}

异常由以下内容抛出

Newtonsoft.Json.Linq.JTokenWriter.WriteValue(Int64 value)

序列化很好用,这里是我使用的代码。
using (StreamWriter reader = new StreamWriter("myFile.json"))
{
   using (JsonReader jsWriter = new JsonWriter(reader))
   {
      JsonTextWriter jsonWriter = new JsonTextWriter(jsWriter) { Formatting = Formatting.Indented };
      JsonSerializer ser = new JsonSerializer();
      ser.Serialize(jsonWriter, dataObject, dataObject.GetType());
      jsonWriter.Flush();
    }
}}

在反序列化过程中我是否做错了什么?你能帮忙提供一种反序列化大型JSON对象的方法吗?

谢谢。


  1. 确保您正在运行64位应用程序。如果您正在以32位模式运行,则可能会耗尽内存。
  2. 内存不足异常的完整回溯是什么?您是否在JsonConverter中耗尽了内存?
- dbc
我正在运行一个32位应用程序,执行代码 dataObject = serializer.Deserialize<T>(jsReader); 时出现了内存不足的问题,并且抛出异常的函数是 Newtonsoft.Json.Linq.JTokenWriter.WriteValue(Int64 value)。 - cmarlowe88
2个回答

5
根据Newtonsoft.Json性能技巧,您的方法应该有效(因为您通过流读取并且应该从文件中获取部分)。我无法弄清楚您的代码为什么不起作用。
但是您可以尝试另一种方法,该方法在下一篇文章中描述 - 使用Json.NET解析大型记录

可能将1GB的Json反序列化成一个对象时,它并不会“适应”内存。 - Matteo Umili

0
我知道这是一个老问题,但我刚刚遇到了一个50GB的json文件的同样问题。 这是我的解决方案:
using (FileStream sr = new FileStream(jsonFile, FileMode.Open, FileAccess.Read))
using (StreamReader fileReader = new StreamReader(sr))
using (JsonTextReader jsonReader = new JsonTextReader(fileReader))
{
    JsonSerializer jsonSerializer = new JsonSerializer();
    List<JObject> documentBatch = new List<JObject>();

    while (jsonReader.Read())
    {
        if (jsonReader.TokenType == JsonToken.StartObject)
        {                   
            JObject document = jsonSerializer.Deserialize<JObject>(jsonReader);             
            documentBatch.Add(document);
            
            if (documentBatch.Count >= 1000) // Adjust the batch size as needed
            {
                foreach (JObject item in documentBatch)
                {
                    //do your stuff
                }
                
                documentBatch.Clear();
            }               
        }
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接