BinaryFormatter序列化大容量数据, 会产生System.OutOfMemoryException异常

homeway78 2009-05-08 02:03:13
以下为示例代码, 当输入15000时或者以上会产生System.OutOfMemoryException异常,

另外同样的数据源, 使用DataTable和Object执行序列化, 得到的流长度差了两倍.

如何才能突破BinaryFormatter的容量, 另外DataTable和Object序列化后的不同如何解决.


protected void Serialize(int rowCount)

{

Console.WriteLine("时间:{0:yyyy-MM-dd HH:mm:ss ddd}, 序列化数据, 共{1}行.", DateTime.Now, rowCount);

//创建数据源

DataTable dt = new DataTable();

for (int index = 0; index < 100; index++)

{

dt.Columns.Add(string.Format("Col{0}", index), typeof(string));

}

for (int j = 0; j < 2e4; j++)

{

DataRow newRow = dt.NewRow();

for (int index = 0; index < 100; index++)

{

newRow[string.Format("Col{0}", index)] = string.Format("数值({0}) 加 数字({1}) 等于 值({2})", index, j, index + j);

}

dt.Rows.Add(newRow);

}

Console.WriteLine("时间:{0:yyyy-MM-dd HH:mm:ss ddd}, 已建立数据源.", DateTime.Now);

//序列化

MemoryStream stream = new MemoryStream();

new BinaryFormatter().Serialize(stream, dt);

Console.WriteLine("时间:{0:yyyy-MM-dd HH:mm:ss ddd}, 流长度{1:#,###}, 类型DataTable.", DateTime.Now, stream.Length);

//序列化

object obj = dt as object;

new BinaryFormatter().Serialize(stream, obj);

Console.WriteLine("时间:{0:yyyy-MM-dd HH:mm:ss ddd}, 流长度{1:#,###}, 类型Object.", DateTime.Now, stream.Length);

}
...全文
993 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
zgke 2009-05-09
  • 打赏
  • 举报
回复
BinaryFormatter.Serialize(Stream,obj);
写入后是写到当前Stream的后面.不是重新生成一个Stream.
homeway78 2009-05-09
  • 打赏
  • 举报
回复
确实同一个对象被序列化了两次, 是个Bug.
那么BinaryFormatter是否有分布序列化的方式呢, 比如每次只写入固定长度的字节到流中, 然后转存出去.
wuyq11 2009-05-08
  • 打赏
  • 举报
回复
LS正确,序列化了两次

参考
参考
真相重于对错 2009-05-08
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 lextm 的回复:]
为了保证但序列化时能够有足够的类型信息,在你在序列化的时候,类型信息也是写入到序列化流内部的。由于DataTable和object的类型信息肯定不一样多,所以会造成序列化结果不一样。或者假设序列化结果完全一样,那么反序列化的结果难道会两样?那时候你又怎么区分是DataTable还是object呢?

至于OOM,要看到底是哪里溢出了。一般来说改用64位的操作系统可以减少OOM的情况,另外就是尽可能不要序列化那么大的对象了。
[/Quote]
瞎说,楼主 的代码错误
MemoryStream stream = new MemoryStream();

new BinaryFormatter().Serialize(stream, dt);

Console.WriteLine("时间:{0:yyyy-MM-dd HH:mm:ss ddd}, 流长度{1:#,###}, 类型DataTable.", DateTime.Now, stream.Length);

//序列化

object obj = dt as object;

new BinaryFormatter().Serialize(stream, obj);
同一个stream序列化同一个对象最后流大小当然是第一次序列化的一倍
lextm 2009-05-08
  • 打赏
  • 举报
回复
为了保证但序列化时能够有足够的类型信息,在你在序列化的时候,类型信息也是写入到序列化流内部的。由于DataTable和object的类型信息肯定不一样多,所以会造成序列化结果不一样。或者假设序列化结果完全一样,那么反序列化的结果难道会两样?那时候你又怎么区分是DataTable还是object呢?

至于OOM,要看到底是哪里溢出了。一般来说改用64位的操作系统可以减少OOM的情况,另外就是尽可能不要序列化那么大的对象了。
源码下载地址: https://pan.quark.cn/s/a4b39357ea24 Altium Designer 18是一款功能丰富的电子设计自动化工具,其集成了电路原理图绘制、PCB布局规划、三维视图展示、电路仿真分析以及生产文件生成等多项核心功能,为电子工程师们提供了一个全面的硬件设计解决方案。该软件的官方中文指导材料系统地阐述了从项目初始阶段到最终完成的全过程操作方法。 在“AD18 官方中文指导材料”中,使用者可以掌握以下核心内容要点: 1. **系统配置与界面认知**:熟悉Altium Designer 18的工作平台,涵盖菜单选项、工具栏配置、工作区域安排,以及个性化工作界面的设定方法。 2. **项目创建流程**:掌握如何建立新的项目工程,包括工程参数配置、项目模板选取,以及项目文件的添加操作。 3. **电路图绘制技术**:学习电路原理图的绘制流程,包括元件库的维护管理、元件放置技巧、连接线路绘制、属性编辑操作,以及网络表的自动生成方法。 4. **元件库构建与管理**:了解如何建立自定义元件库,执行元件的导入与导出任务,以及利用Altium Designer自带的元件资源库。 5. **PCB布局设计方法**:掌握PCB设计的基本准则,如元件布局策略、布线技巧、层叠结构调整、布线规则优化,以及冲突检测与短路处理技术。 6. **设计规范与约束条件**:理解设定设计规范和电气约束条件的关键性,包括间距参数设定、焊盘尺寸规格、过孔尺寸要求等,以及运用规则检查进行设计验证的流程。 7. **三维模型整合应用**:学习如何将三维模型与PCB设计内容相结合,以实现更为直观的机械配合验证。 8. **电路性能仿真技术**:掌握使用Altium Des...

111,129

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Creator Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧