Note: This blog has been moved to http://blog.yuvisense.net

Monday, April 17, 2006

[Tech]Seemingly Memory Optimization Trick for Class B people....

Well, let me explain the title a bit. According to me, there are 4 kinds of computer Users :
  • Class A, who don't know anything, and know that they don't know anything
  • Class B, who know something, and think they know everything
  • Class C, who know something, and know that they know only something
  • Class D, who know more than something, and know that they know more than something
Well, Class A would be my Dad : He knows that he doesn't know anything, about computers, that is.[Note to Self : There's a Sneaky Creature behind my back, so be careful] Class B would be me about a year ago : I had no idea of the internet, infact, I thought that .NET = the Web;) Thankfully, due to the Internet, Wikipedia, MSDN, CodeProject, Blogs and my Cousin Sudar, I'm now in Class C. OK. If you've been reading a lot, you'dve come across this before, but if you haven't hear. Now, a Class B guy opens up a .NET app, goes to task manager, and finds rocket-high Memory consumption. So, he thinks, "Ooh! This app is *bloated* and takes up soooo much memory. No wonder it was made by Microsoft". #Region "Feel Free To Ignore This If You Don't Like Theory" What he doesn't know is that what Task Manager calls as "Mem Usage", is really "Working Set Memory Usage". Well, to understand Working Set, we have to understand the concept of "Paged Virtual Memory Management", which is used by Windows. Now, let me get a nice analogy here. The Working Set is like a Scratch Page for your Maths : It's fast, it's on your RAM, and it's the place where you do most of your calculations. In Single-tasking Environments like DOS, you had only one Page do do everything on. So far, so good... Now, in a Multi-Tasking Environment like Windows, Each Process gets it's Own Scratch Page. It can see only it's own Scratch Page, not another Process's Scratch Page. If you're allocating so much memory that this Scratch Page is full, then Windows writes that to disk, and you get a New Page. If you want to access anything in your older Page, Windows just loads that Page back, and reads that value for you. So, you can never run out of Memory, even if you're allocating 257 MB of Memory with a System that has only 256 MB of RAM, Windows uses Paging to allocate that much Memory. And, all this is transparent to you. You can just pretend that the System had Unlimited Memory, and allocate as much as you want. This system is known as a Virtual Paging Memory System. Hope I'm clear till now. If I am not, then just read this article on Wikipedia on Virtual Memory. So, the Working Set is just the amount of stuff you've stored in Your Current Scratch Page. This, is what Task Manager reports, and it does not count all those Previous Scratch Pages. It's like, you're writing a Maths Exam, and just submit the last page you worked on. So, inorder to get an actual Value of how much Memory your app is using, you need to get the size of all your Pages. And, this Value, confusingly called VM Size by the Task Manager, is almost always higher than than the Working Set, since pages which are old and not frequently accessed are not loaded by Windows untill they are called. You can view this in the Task Manager itself by going to View - Select Columns and checking the Virtual Memory Size checkbox. This gives a realistic View of how much Memory your App is using. Now, also, when an App is minimized, windows unloads all the Pages of the app into Disk. So, the Working Set appears drastically Reduced, but the VM Size remains the same. #End Region Still with me ? Good. Now, I'll show you a neat Trick that satisfies Class B Users by reducing the apparent Memory Usage of your app reported by Task Manager in just 2 Lines of Code. So, if one of your Boss/PM/Teacher/Departmenal Head keeps saying how much memory a .NET app is taking, just use this trick to convince them. So, you first declare this Declare statement, declaring a Win32 API call. It's called SetProcessWorkingSetSize :
Private Declare Function SetProcessWorkingSetSize _ 
	Lib "kernel32.dll" _ 
	(ByVal hProcess As IntPtr, _ 
	ByVal dwMinimumWorkingSetSize As Int32, _
	ByVal dwMaximumWorkingSetSize As Int32) _ 
	As Int32
And, somewhere in your app, prefereably in the end of the Load Event or somewhere else, just keep this piece of code :
        SetProcessWorkingSetSize _
	(System.Diagnostics.Process.GetCurrentProcess.Handle _
	,-1,-1)
So, we are passing the SetProcessWorkingSetSize Function the handle of our Process, and setting the minSize and maxSize to -1, meaning that Windows will Trim them to lowest possible Value. As soon as this line of code executes, you'll find that Task Manager Reports a Mem Usage of below 1 MB. But, VM Size would be normal for a .NET app... This actually doesn't Optimize Memory Usage, but just makes it look like your app is consuming less memory than it really is. Most useful in situations to convince people who don't understand that Windows gives Memory to people as they need it, so Memory Usage isn't actually that Importand for stability of other Apps.... Bottom Line: If you don't understand any of the Crap I wrote above, just remember this : If someone is asking you to reduce their .NET Memory Consumption, just fake it to them with the Above code. P.S. Man,this took a whole hour! I just can't believe time flies sooo fast when you are doing something you love... If you're still with me, I'd want to hear a comment....:D

2 Comments:

Blogger Ramesh RV said...

Simply Superb.....

Really good one, pat on your back.

4/17/2006 04:51:00 AM  
Blogger Aswin Anand T.H. said...

nice da :D

4/17/2006 07:37:00 AM  

Post a Comment

<< Home