读取字符串时出现OutOfMemoryException



我有一个C#.NET系统,它接受JSON数据馈送并使用Newtonsoft.Json.JsonConvert.DeserializeObject转换器将其转换为对象。

只要JSON字符串低于一定大小(几Mb),这个过程就可以完美工作,但一旦返回的数据很大(几乎100Mb),我就会得到错误OutOfMemoryException

此代码适用于小数据:

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

但在最后一行(DownloadString)上爆炸

我试着改为这个,它也适用于小数据,但当数据大小增加时,它在ReadToEnd行上仍然失败了。

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();
        }
    }
}

最后我尝试了这个,它起了作用:

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错误:

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

它不喜欢ToString()方法。

它还坠毁了一条像这样的简单线路

string _convertedString = _stringBuilder.ToString();

完整错误为:

中发生类型为"System.OutOfMemoryException"的异常mscorlib.dll,但未在用户代码中处理

该机器正在运行具有16Gb内存的64位窗口。

那么,我有什么选择?

我想要的只是一个(非常大的)JSON字符串中的IQueryable<MyObject>

您的代码基本上模拟了StreamReader.ReadToEnd的操作,读取一个大响应所需的内存至少是它的4倍(字符串响应本身的内存、StringBuilder的内部缓冲区、所有中间临时字符串和最终字符串的大小)。

您可以通过使用JsonTextReader直接从流进行反序列化来避免这种情况。从文档样本复制:

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

O

相关内容

  • 没有找到相关文章

最新更新