c# - 使用 protobuf-net 时如何处理 System.OutOfMemoryException?
问题描述
我在 ac# 应用程序中使用 protobuf-net 来加载和保存我的程序的“项目文件”。在保存时间,程序会创建一个 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
,但我看不到要评论的地方。
请注意,这会更改数据布局,因此应视为重大更改。
推荐阅读
- javascript - 迭代本地 JSON 文件时如何省略“默认”条目?
- flutter - 附加到多个滚动视图的 ScrollController
- python - LDA Gensim OOM Exception 因为大语料库
- python - 如何生成随机数并将它们存储在随机数量的可调用变量中?
- php - 如何在 php 文件中的 div 内放置一个空变量,然后在另一个 php 文件中定义它
- performance - 为什么在循环中包含额外的汇编指令会提高执行速度?
- android - 找不到 android.support.v7.app.ActivityCompat
- database - 如何在flutter中将图像数据保存到sqflite数据库以进行持久化
- arrays - VBA多维数组,为什么第二维的第一个值被复制到第一维的第一个值中
- javascript - 替换后,跳过字符串的那部分 - Regex Javascript