我正在尝试处理非常大量的数据(~1000个单独的文件,每个文件大约30 MB),以便用作机器学习算法的训练阶段的输入。使用JSON格式化的原始数据文件,我使用Json.NET的JsonSerializer类对它们进行反序列化。在程序结束时,Newtonsoft.Json.dll抛出 'OutOfMemoryException' 错误。有没有办法减少内存中的数据,或者我是否必须改变我的所有方法(例如切换到像Spark这样的大数据框架)来处理这个问题?
public static List<T> DeserializeJsonFiles<T>(string path)
{
if (string.IsNullOrWhiteSpace(path))
return null;
var jsonObjects = new List<T>();
//var sw = new Stopwatch();
try
{
//sw.Start();
foreach (var filename in Directory.GetFiles(path))
{
using (var streamReader = new StreamReader(filename))
using (var jsonReader = new JsonTextReader(streamReader))
{
jsonReader.SupportMultipleContent = true;
var serializer = new JsonSerializer();
while (jsonReader.Read())
{
if (jsonReader.TokenType != JsonToken.StartObject)
continue;
var jsonObject = serializer.Deserialize<dynamic>(jsonReader);
var reducedObject = ApplyFiltering(jsonObject) //return null if the filtering conditions are not met
if (reducedObject == null)
continue;
jsonObject = reducedObject;
jsonObjects.Add(jsonObject);
}
}
}
//sw.Stop();
//Console.WriteLine($"Elapsed time: {sw.Elapsed}, Elapsed mili: {sw.ElapsedMilliseconds}");
}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex}")
return null;
}
return jsonObjects;
}
感谢。
答案 0 :(得分:2)
这对牛顿软件来说并不是一个问题。您正在将所有这些对象读入内存中的一个大列表中。它要求JsonSerializer
创建另一个对象并且失败。
您需要从方法返回IEnumerable<T>
,每个对象yield return
,并在调用代码中处理它们,而不将它们存储在内存中。这意味着迭代IEnumerable<T>
,处理每个项目,写入磁盘或任何他们需要的地方。