读字符串时OutOfMemoryException异常 [英] OutOfMemoryException when reading a string

查看:303
本文介绍了读字符串时OutOfMemoryException异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个C#.NET系统,需要一个 JSON 数据饲料用它转换为一个对象的 Newtonsoft.Json.JsonConvert.DeserializeObject 转换器。

I have a C# .NET system that takes a JSON data feed and converts it to an object using the Newtonsoft.Json.JsonConvert.DeserializeObject converter.

这过程中完美的作品,只要JSON字符串是具有一定规模(几MB)以下,但只要返回数据是大(几乎100兆),我得到 OutOfMemoryException异常

This process works perfect as long as the JSON string is below a certain size (a few Mb) but as soon as the returned data is large (almost 100Mb) I get the error OutOfMemoryException

此代码的伟大工程为小数据错误:

This code works great for small data:

// WebClient ------------------------------------------------------------------
var _client = new System.Net.WebClient();
var _content = _client.DownloadString(_url);



但在最后一行炸毁( DownloadString

我试图改变这个也适用于小型的数据,但它仍然炸毁了在 ReadToEnd的行当大小的数据增长。

I tried changing to this which also works for small data but it still blew up on the ReadToEnd line when the data grew in size.

using (var _response = (System.Net.HttpWebResponse)_request.GetResponse())
{
    using (System.IO.Stream _dataStream = _response.GetResponseStream())
    {
        using (System.IO.StreamReader _streamReader = new System.IO.StreamReader(_dataStream))
        {
            string _responseFromServer = _streamReader.ReadToEnd();
        }
    }
}



最后,我想这里面工作

Finally I tried this which worked:

StringBuilder _stringBuilder = new StringBuilder();
using (var _response = (System.Net.HttpWebResponse)_request.GetResponse())
{
    using (System.IO.Stream _dataStream = _response.GetResponseStream())
    {
        using (System.IO.StreamReader _streamReader = new System.IO.StreamReader(_dataStream))
        {
            while (!streamReader.EndOfStream)
            {
                char[] _buffer = new char[4096];
                _streamReader.ReadBlock(_buffer, 0, _buffer.Length);
                var _bufferString = new String(_buffer);
                _stringBuilder.Append(_bufferString);
            }
        }
    }
}



不过,它炸毁了与 OutOfMemoryException异常错误,当它到了下一行的位置:

But it blew up with an OutOfMemoryException error when it got to the next line here:

var _results = Newtonsoft.Json.JsonConvert.DeserializeObject<List<MyObject>>(_stringBuilder.ToString());



它不喜欢的ToString()方法。

这也应声像

string _convertedString = _stringBuilder.ToString();



完整的错误是:

The full error is:

型'的System.OutOfMemoryException的异常出现在
mscorlib.dll中,但用户代码

An exception of type 'System.OutOfMemoryException' occurred in mscorlib.dll but was not handled in user code

本机运行的是64位的窗口16GB内存。

The machine is running 64bit windows with 16Gb of memory.

那么,什么是我的选择?

So, what are my options?

我要的是一个的IQueryable< MyObject的方式> 从(超大型) JSON 字符串

All I want is an IQueryable<MyObject> from a (very large) JSON string.

推荐答案

您的代码基本上是模仿什么的 StreamReader.ReadToEnd 的那样,至少服用4次读大响应(字符串响应本身的存储器中所需要的存储器,所述的StringBuilder的内部缓冲区中,所有的中间临时串的大小和最终的字符串)。

Your code essentially emulates what StreamReader.ReadToEnd does, taking at least 4 times the memory needed to read a large response (the memory of the string response itself, the StringBuilder's internal buffer, the size of all the intermediate temporary strings and the final string).

可以通过从直接与JsonTextReader流反序列可以避免这种情况。从文档样本复制:

You can avoid this by deserializing from the stream directly with a JsonTextReader. Copying from the documentation sample:

using (var json= new JsonTextReader(streamReader))
{
    JsonSerializer serializer = new JsonSerializer();
    return (List<MyObject>)serializer.Deserialize(json, typeof(List<MyObject>));
}



0

O

这篇关于读字符串时OutOfMemoryException异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆