使用 protobuf-net 时如何处理 System.OutOfMemoryException?
How to handle System.OutOfMemoryException when using protobuf-net?
我在 C# 应用程序中使用 protobuf-net 来加载和保存我的程序 'project files'。在保存时,程序会创建一个 ProjectData 对象并向其添加许多不同的对象 - 请参阅下面的一般原则。
static ProjectData packProjectData()
{
ProjectData projectData = new ProjectData();
projectData.projectName = ProjectHandler.projectName;
foreach (KeyValuePair<int, Module> kvp in DataHandler.modulesDict)
{
projectData.modules.Add(serializeModule(kvp.Value));
}
return projectData;
}
[ProtoContract]
public class ProjectData
{
[ProtoMember(1)]
public List<SEModule> modules = new List<SEModule>();
[ProtoMember(2)]
public string projectName = "";
}
创建后,将其压缩并保存到磁盘。我遇到的问题是,当模块数量变得非常大(40,000+)时,在 packProjectData 函数期间报告 System.OutOfMemoryException。
我已经看到过类似的问题,但这些问题没有明确的答案来解决问题。如果有人能给我一个具体的解决方案,或者可以遵循的一般原则,将不胜感激。
我们在这里谈论的是哪种尺寸?这很可能是由于长度前缀需要缓冲——v3 将解决这个问题,但现在——如果文件很大,一个实用的解决方法可能是:
[ProtoContract]
public class ProjectData
{
[ProtoMember(1, DataFormat = DataFormat.Grouped)]
public List<SEModule> modules = new List<SEModule>();
[ProtoMember(2)]
public string projectName = "";
}
这会更改 SEModule
项目的内部编码格式,因此不需要长度前缀。同样的方法也可能对 SEModule
中的某些元素有用,但我看不到评论。
请注意,这会更改数据布局,因此应被视为重大更改。
我在 C# 应用程序中使用 protobuf-net 来加载和保存我的程序 'project files'。在保存时,程序会创建一个 ProjectData 对象并向其添加许多不同的对象 - 请参阅下面的一般原则。
static ProjectData packProjectData()
{
ProjectData projectData = new ProjectData();
projectData.projectName = ProjectHandler.projectName;
foreach (KeyValuePair<int, Module> kvp in DataHandler.modulesDict)
{
projectData.modules.Add(serializeModule(kvp.Value));
}
return projectData;
}
[ProtoContract]
public class ProjectData
{
[ProtoMember(1)]
public List<SEModule> modules = new List<SEModule>();
[ProtoMember(2)]
public string projectName = "";
}
创建后,将其压缩并保存到磁盘。我遇到的问题是,当模块数量变得非常大(40,000+)时,在 packProjectData 函数期间报告 System.OutOfMemoryException。
我已经看到过类似的问题,但这些问题没有明确的答案来解决问题。如果有人能给我一个具体的解决方案,或者可以遵循的一般原则,将不胜感激。
我们在这里谈论的是哪种尺寸?这很可能是由于长度前缀需要缓冲——v3 将解决这个问题,但现在——如果文件很大,一个实用的解决方法可能是:
[ProtoContract]
public class ProjectData
{
[ProtoMember(1, DataFormat = DataFormat.Grouped)]
public List<SEModule> modules = new List<SEModule>();
[ProtoMember(2)]
public string projectName = "";
}
这会更改 SEModule
项目的内部编码格式,因此不需要长度前缀。同样的方法也可能对 SEModule
中的某些元素有用,但我看不到评论。
请注意,这会更改数据布局,因此应被视为重大更改。