当我使用内存流序列化和反序列化对象时,我想提供一些提高应用程序内存效率的技巧。
对于这个例子,我想将一个包含大型DataTable的类转换为字节,以便通过TCP发送它。
让我们假设我有以下要序列化的类:
[Serializable]
public class DataContainer
{
public string TableName { get; set; }
public DataTable DataTableData { get; set; }
}
以下表格申请:
1)创建一个表并将其存储在DataContainer
中2)序列化DataContainer
3)反序列化DataContainer
public partial class SerialiseDesirialise : Form
{
private DataContainer dc;
private byte[] byteSD;
public SerialiseDesirialise()
{
InitializeComponent();
dc = new DataContainer();
}
private void runBtn_Click(object sender, EventArgs e)
{
dc.TableName = "Memory Usage Test";
CreateTable();
SerialiseObj();
DeserialiseObj();
dc = null;
byteSD = null;
int k = 0;
}
private void CreateTable()
{
DataTable dt = new DataTable();
dt.Columns.Add("Column 1", typeof(string));
dt.Columns.Add("Column 2", typeof(string));
dt.Columns.Add("Column 3", typeof(string));
string one = new Guid().ToString();
string two = new Guid().ToString();
string three = new Guid().ToString();
for (int i = 0; i < 1000000; i++)
{
dt.Rows.Add(one, two, three);
}
dc.DataTableData = dt;
}
private void SerialiseObj()
{
BinaryFormatter f = new BinaryFormatter();
using (MemoryStream ms = new MemoryStream())
{
f.Serialize(ms, dc);
byteSD = new byte[ms.Length];
byteSD = ms.ToArray();
ms.Dispose();
}
}
private void DeserialiseObj()
{
BinaryFormatter f = new BinaryFormatter();
using (MemoryStream ms = new MemoryStream())
{
ms.Write(byteSD, 0, byteSD.Length);
ms.Position = 0;
DataContainer _dc = f.Deserialize(ms) as DataContainer;
_dc = null;
ms.Dispose();
}
}
}
我录制了以下进程内存值:
1)当我运行应用程序时,进程内存= 17MB
2)当CreateTable()完成时,进程内存= 141MB(这可以理解,因为它的大表)
3)当f.Serialize(ms,dc)行完成时,进程内存= 3GB(为什么?我期望一个小得多的值,因为ms.Length是338779361字节,等于338MB)
4)完成SerialiseObj()后,进程内存= 1.6GB
5)再次进入DeserialiseObj()时,进程内存达到3GB并降至1.6GB
6)最后在整个代码完成后,即使我将每个变量设置为null,进程内存= 1.6GB(为什么不降至17MB?)
我想知道你是否可以向我解释上面发生的原因以及如何通过不达到如此高的进程内存并在代码完成时返回初始级别来改进我的应用程序。