I would like some tips to improve the memory efficiency of my application when I serialize and deserialize an object using a memory stream.
For this example I would like to convert a class which contains a large DataTable into bytes in order to send it over TCP.
Lets assume i have the following class which i want to serialize:
[Serializable]
public class DataContainer
{
public string TableName { get; set; }
public DataTable DataTableData { get; set; }
}
And the following Form application:
1) Create a table and store it in a DataContainer
2) Serialize the DataContainer
3) Deserialize the 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();
}
}
}
I recorded the following Process Memory values:
1) When I run the application the Process Memory = 17MB
2) When CreateTable() is completed the Process Memory = 141MB (which s understandable since its a big table)
3) When the line f.Serialize(ms, dc) is completed the Process Memory = 3GB (why? i would expect a much smaller value since the ms.Length is 338779361 bytes which is equal to 338MB)
4) After SerialiseObj() is completed the Process Memory = 1.6GB
5) Again when entering DeserialiseObj() the Process Memory reaches 3GB and drops to 1.6GB
6) Finally after the whole code is completed even if I set every variable to null the Process Memory = 1.6GB (why does not drop to 17MB?)
I was wondering if you could explain to me why the above occurs and how can I improve my application by not reaching so high Process Memory and returning to initial levels when the code is completed.