【问题标题】:Getting an OutOfMemoryException while serialising to JSON?序列化为 JSON 时出现 OutOfMemoryException?
【发布时间】:2012-01-27 16:19:21
【问题描述】:

我正在序列化,MultiDictionary<String,Object>

http://powercollections.codeplex.com/ to json .

它有 618 个元素,元素被深度嵌套,即单个对象中可能有几个类似字典的对象。我正在使用 JSON.Net

String json = JsonConvert.SerializeObject(json, Newtonsoft.Json.Formatting.Indented);

我错过了什么?

更多信息:- 这在我使用动态之前工作正常,我不得不切换到 MultiDictionary 以允许多个同名属性。它适用于大多数情况,只有当项目数量很大时才会中断。

更新:-

我已经能够控制内存消耗,但减少了一些递归添加到每个元素的元素。

【问题讨论】:

    标签: c# json serialization json.net


    【解决方案1】:

    假设您没有循环引用 - 如果您无法将整个内容存储在内存中,请使用 Newtonsoft v4.0.30319 中的 StreamWriter(JsonWriter 或 TextWriter)

    using (TextWriter writer = File.CreateText("LocalJSONFile.JSON"))
    {
        var serializer = new JsonSerializer();
        serializer.Serialize(writer, myObject);
    }
    

    如果您要传递字符串,请使用 JsonWriter

    StringBuilder sb = new StringBuilder();
    StringWriter sw = new StringWriter(sb);
    
    using(JsonWriter writer = new JsonTextWriter(sw))
    {
      var serializer = new JsonSerializer();
      serializer.Serialize(writer, myObject);
    }
    

    【讨论】:

    • 非常感谢。经过这么多的头痛之后,您的第一个关于 TextWriter 的解决方案终于奏效了。我希望,如果我能投票给你 10 次。
    • 如何通过设置?比如 PreserveReferencesHandling = PreserveReferencesHandling.Objects, ReferenceLoopHandling = ReferenceLoopHandling.Serialize
    • 同样没有设置,即使我的电脑有 4 GB RAM,上面的代码也失败了。
    • 您要在大对象本身中保存函数设置?我会推荐几件事 - 即不要那样做。将这些值保存在特定于配置的某个对象中,并让大型 JSON 仅用于数据。如果你不能这样做,那么我建议对单个对象进行两次扫描,第一次提取设置,第二次处理大型 JSON。
    【解决方案2】:

    您似乎遇到了导致OutOfMemoryExceptionCiruclar Reference,或者您的对象对于您的内存来说太大了。使用NDepend 进行检查。

    您可能会发现有用的getting the total size of your objects

    【讨论】:

    【解决方案3】:

    如果不知道被序列化对象的确切结构,就很难判断,但有可能由于对象图太大,某处可能存在循环引用(指向对象的对象又指向第一个对象),创建一个无限循环的序列化。

    编辑:

    您可以使用诸如NDepend 之类的工具来找出循环引用的位置。试试试用版。

    【讨论】:

      猜你喜欢
      • 2014-08-27
      • 1970-01-01
      • 1970-01-01
      • 2022-09-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多