Click here to Skip to main content
15,913,941 members
Home / Discussions / C#
   

C#

 
GeneralRe: How to code this in C# Pin
Guangli(Glen) Liu9-May-07 8:08
professionalGuangli(Glen) Liu9-May-07 8:08 
AnswerRe: How to code this in C# Pin
Dave Doknjas9-May-07 14:41
Dave Doknjas9-May-07 14:41 
GeneralRe: How to code this in C# Pin
Guangli(Glen) Liu10-May-07 5:18
professionalGuangli(Glen) Liu10-May-07 5:18 
QuestionProblem with fading pictures Pin
Kasic Slobodan9-May-07 7:33
Kasic Slobodan9-May-07 7:33 
QuestionPing in wireless network Pin
Chayan (cse student)9-May-07 7:26
Chayan (cse student)9-May-07 7:26 
AnswerRe: Ping in wireless network Pin
MrEyes9-May-07 7:33
MrEyes9-May-07 7:33 
AnswerRe: Ping in wireless network Pin
Dave Kreskowiak9-May-07 7:51
mveDave Kreskowiak9-May-07 7:51 
QuestionManaging Memory and Resources [modified] Pin
MrEyes9-May-07 7:22
MrEyes9-May-07 7:22 
Hello all,

I need some advice relating to managing memory and resources within the .NET Framework. Basically I have an application that from time to time will need to perform the following actions on 200mb+ strings:

App A
1) Compress (using SharpZipLib)
2) Break the compressed byte[] into and array of byte[] chunks
3) Push each chunk onto a WebService

App B
1) Receive chunks from WebService
2) Reconstruct chunks into a single byte[]
2) Uncompress

As you can imagine this takes massive amounts of resources, infact my first stab (for only a 25mb string) resulted in peak memory usage around the 300mb mark.

After some research I found that I can force the GC to collect unused objects, and therefore littered the code with this at relevant points. This resulted in a memory usage peak of around 200mb, better but still not perfect.

So now I am looking for alternatives. At the moment I am mainly looking at doing all the work in an AppDomain and then once completed unload and kill this. However I would appreciate any input on alternative designs.

Whilst I release this probably a bit much for a simple question, the following is the code I currently use. While this works (for small amounts of data), the design really isnt scaleable enough to handle large inputs (200mb+)

...
...
//deflate and chunk
object[] outData = DeflateAndChunk(data);
...
...
//dechunk and inflate
string reconstructedData = DechunkAndInflate(outData);
...
...


private static byte[] DeChunkData(object[] baseData)
{
	int returnLength = 0;
	foreach(byte[] ba in baseData)
	{
		returnLength += ba.Length;
	}

	byte[] readBuffer = new byte[returnLength];
	using (Stream outStream = new MemoryStream(readBuffer))
	{
		
		for (int loop=0; loop<baseData.Length; loop++)
		{
			byte[] dataChunk = (byte[])baseData[loop];
			outStream.Write(dataChunk, 0, dataChunk.Length);	
			baseData[loop] = null; //null of the bytes that are no longer needed, every little helps
		}


		outStream.Flush();
		outStream.Close();
	}

	GC.Collect();

	return readBuffer;
}

private static object[] ChunkData(byte[] baseData, int chunkSize)
{
	int returnArraySize = baseData.Length / chunkSize;
	int baseDataModulus = baseData.Length % chunkSize;
	if (baseDataModulus > 0)
	{
		returnArraySize++;
	}
	object[] returnData = new object[returnArraySize];

	using (Stream baseDataStream = new MemoryStream(baseData))
	{
		baseData = null;

		for (int loop=0;loop < returnArraySize; loop++)
		{
			int workingChunkSize = chunkSize;

			if (loop == returnArraySize)
			{
				workingChunkSize = baseDataModulus;
			}

			byte[] buffer = new byte[workingChunkSize];
			baseDataStream.Read(buffer, 0, workingChunkSize);
			returnData[loop] = buffer;
		}

		baseDataStream.Flush();
		baseDataStream.Close();
	}

	GC.Collect();

	return returnData;
}

public static object[] DeflateAndChunk(string inputMessage)
{
	//compress data and get checksum
	long adler32Checksum = 0;
	byte[] compressedData = CompressData(inputMessage, out adler32Checksum);

	inputMessage = null;
	
	//TODO - BEGIN - Define chunk sizes (config? Based on data size?)
	int chunkSize = 1000;
	//TODO - END Define chunk sizes (config? Based on data size?)

	//chunk data based on params
	object[] chunkedData = ChunkData(compressedData, chunkSize);

	//TODO - BEGIN - thread off and send chunks using config from WS call
	//WS calls here, least of my worries until memory
	//usage for chunking and compression is sorted
	//TODO - END - thread off and send chunks using config from WS call

	//method only returns so it can be tested
	return chunkedData;
}

public static string DechunkAndInflate(object[] inputData)
{
	byte[] deChunkedData = DeChunkData(inputData);

	byte[] inflatedData = UnCompressData(deChunkedData);
	
	deChunkedData = null;

	return System.Text.ASCIIEncoding.ASCII.GetString(inflatedData);
}

private static byte[] CompressData(string message, out long adler32Checksum)
{
	byte[] returnData = null;

	//create base streams
	using (Stream inStream = new MemoryStream(System.Text.ASCIIEncoding.ASCII.GetBytes(message)))
	{
		message = null;

		using (Stream outStream = new MemoryStream())
		using (ZipStreams.DeflaterOutputStream deflatorStream = new ZipStreams.DeflaterOutputStream(outStream, 
			new ZipCompression.Deflater(ZipCompression.Deflater.BEST_SPEED)))
		{

			....
			//standard sharpzip code for compression
			....
		}
	}

	//calculate checksums
	BaseCompression.Checksums.Adler32 ad32 = new BaseCompression.Checksums.Adler32();
	ad32.Update(returnData);
	adler32Checksum = ad32.Value;

	//force garbage collection
	GC.Collect();

	return returnData;
}

private static byte[] UnCompressData(byte[] deflatedData)
{
	byte[] returnData = null;

	//create inflator streams
	using (Stream inStream = new MemoryStream(deflatedData))
	{
		deflatedData = null;

		using (MemoryStream outStream = new MemoryStream())
		using (ZipStreams.InflaterInputStream inflatorStream = new ZipStreams.InflaterInputStream(inStream))
		{
			....
			//standard sharpzip code for uncompression
			....
		}
	}

	//force garbage collection
	GC.Collect();

	//return
	return returnData;
}



-- modified at 13:38 Wednesday 9th May, 2007
AnswerRe: Managing Memory and Resources Pin
Luc Pattyn9-May-07 7:43
sitebuilderLuc Pattyn9-May-07 7:43 
GeneralRe: Managing Memory and Resources Pin
MrEyes9-May-07 7:50
MrEyes9-May-07 7:50 
GeneralRe: Managing Memory and Resources Pin
Judah Gabriel Himango9-May-07 12:41
sponsorJudah Gabriel Himango9-May-07 12:41 
GeneralRe: Managing Memory and Resources Pin
MrEyes9-May-07 22:51
MrEyes9-May-07 22:51 
GeneralRe: Managing Memory and Resources Pin
Scott Dorman9-May-07 13:01
professionalScott Dorman9-May-07 13:01 
AnswerRe: Managing Memory and Resources Pin
Scott Dorman9-May-07 13:08
professionalScott Dorman9-May-07 13:08 
GeneralRe: Managing Memory and Resources Pin
MrEyes9-May-07 22:53
MrEyes9-May-07 22:53 
QuestionValue From A Cell Pin
BlitzPackage9-May-07 6:09
BlitzPackage9-May-07 6:09 
AnswerRe: Value From A Cell Pin
Nouman Bhatti9-May-07 20:24
Nouman Bhatti9-May-07 20:24 
QuestionEditing list thru the Enumerator Pin
LCI9-May-07 6:00
LCI9-May-07 6:00 
AnswerRe: Editing list thru the Enumerator Pin
Tarakeshwar Reddy9-May-07 6:19
professionalTarakeshwar Reddy9-May-07 6:19 
GeneralRe: Editing list thru the Enumerator Pin
LCI9-May-07 6:39
LCI9-May-07 6:39 
GeneralRe: Editing list thru the Enumerator Pin
Tarakeshwar Reddy9-May-07 6:54
professionalTarakeshwar Reddy9-May-07 6:54 
GeneralRe: Editing list thru the Enumerator Pin
Patrick Etc.9-May-07 10:47
Patrick Etc.9-May-07 10:47 
Questionanimated image Pin
sujithkumarsl9-May-07 5:32
sujithkumarsl9-May-07 5:32 
AnswerRe: animated image Pin
Tarakeshwar Reddy9-May-07 5:46
professionalTarakeshwar Reddy9-May-07 5:46 
GeneralRe: animated image Pin
sujithkumarsl9-May-07 19:07
sujithkumarsl9-May-07 19:07 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.