Json.Net反序列化内存不足问题

Dan*_*elG 7 c# base64 out-of-memory json.net

我有一个Json,其中包含一个存储base64编码字符串的数据字段.这个Json被序列化并发送给客户端.

在客户端,newtonsoft json.net反序列化器用于返回Json.但是,如果数据字段变大(~400 MB),则解串器将抛出内存不足异常:数组维度超出支持的范围.我还在Task-Manager中看到,内存消耗确实快速增长.

任何想法为什么会这样?是否有json字段的最大大小?

代码示例(简化):

HttpResponseMessage responseTemp = null;
responseTemp = client.PostAsJsonAsync(client.BaseAddress, message).Result;

string jsonContent = responseTemp.Content.ReadAsStringAsync.Result;
result = JsonConvert.DeserializeObject<Result>(jsonContent);
Run Code Online (Sandbox Code Playgroud)

结果类:

public class Result
{

    public string Message { get; set; }
    public byte[] Data { get; set; }

}
Run Code Online (Sandbox Code Playgroud)

更新:

我认为我的问题不是序列化程序,而只是试图在内存中处理这么大的字符串.在我将字符串读入内存时,应用程序的内存消耗会爆炸.该字符串上的每个操作都是相同的.目前,我认为我必须找到一种方法来处理流并立即停止将所有内容读入内存.

Dil*_*165 14

使用JsonConvert.DeserializeObject读取大型JSON字符串将占用大量内存.因此,有一种方法可以解决这个问题,你可以创建一个JsonSerializer实例,如下所示.

 using (StreamReader r = new StreamReader(filePath))
 {
          using (JsonReader reader = new JsonTextReader(r))
         {
                JsonSerializer serializer = new JsonSerializer();
                T lstObjects = serializer.Deserialize<T>(reader);
        }
}
Run Code Online (Sandbox Code Playgroud)

这里的filePath: - 是你当前的Json文件而 T: - 是你的Generic类型对象.

  • 这应该是公认的答案.它提供了一个很好的实践,而不是解决问题的答案,但只是尽量减少风险.谢谢! (2认同)

dbc*_*dbc 6

我假设你使用的是64位.如果没有,请切换.

完成后,如果您使用.Net 4.5或更高版本,请启用jsonContent.它允许具有最多JsonTextReader条目的数组,即使这会导致底层内存缓冲区大于2 GB.但是,您仍然无法读取长度超过2 ^ 31个字符的单个JSON令牌,因为XmlReader.ReadValueChunk()缓冲了<gcAllowVeryLargeObjects enabled="true" />数组中每个令牌的全部内容,而在.Net中,数组只能容纳int.MaxValue项目.