Click here to Skip to main content
11,642,216 members (64,159 online)
Click here to Skip to main content

Tagged as

Best Practices of Memory Usage

, 25 Jul 2009 CPOL 40.2K 21
Rate this:
Please Sign up or sign in to vote.
A discussion on Memory management in your program.



Lets talk about memory management in practical sense. While we do programming, we often do use of memory in excess of what we need. Generally memory is cheap when you are working with Desktop applications, but while you are doing an ASP.NET application that handles lots of memory of server, excess use of memory and Session may sometimes bring with lots of pain. So let us discuss about best practices of Memory Management so that we can reduce memory wastage.

There is some odd behaviour of the programmers to give memory to the member variables inside a class. This is really odd, because this may sometimes loose extra amount of memory usage unnecessarily. Just take a look on the code below:

public class BadUse
{
   private SqlConnection con = new SqlConnection();
   private DataSet ds = new DataSet("MyData");
   public BadUse() {}
   public BadUse(string connectionString)
   {
       SqlConnection = new SqlConnection(connectionString);
   }
   public BadUse(SqlConnection con)
   {
       this.con = con;
   }
}
If you see the code above, we are definately loosing unnecessary memory of our system. For every class before any calls been made, even before the calls to the constructors, object member initializer is called. Which executes and gives memory to all the member variables. Now in the class demonstrated above, we are making an object of SqlConnection during the initialisation. After that, we are either calling the default constructor or creating object within the constructor. Thus without making use of the already created object, I am creating object again, and thus loosing memory.
Best Practice :

public class GoodUse
{
   private SqlConnection con = null;
   private DataSet ds = null;

public SqlConnection Connection // Better to use Properties
{
    get
    {
        if(this.con == null)   // Always check whether there is an existing object assigned to member
            this.con = new SqlConnection();
    return this.con;
    }
    set
    {
       if(value == null || this.con !=null)
        {
            this.con.dispose();     // Clears out Existing object if member is assigned to Null
            this.con = null;            //    Always better to assign null to member variables
       }
       if(value !=null) this.con = value;
    }
  }
   public GoodUse() {}
   public GoodUse(string connectionString)
   { 
         this.Connection = new SqlConnection(connectionString); //Assignes new object to null member
   }
 public GoodUse(SqlConnection con)
 {
       this.con = con;
  } 
} 

Thus from the above code we are clear, it is always better to have properties rather than accessing objects directly. This gives you an interface to modify each calls later. Similar to this, it is always better to use Event Accessors for accessing Events.
private MyDelegate MyEvent;
public MyDelegate CheckEvent
{
    add
    {
       MyEvent + =value;
    }
    remove
    {
       MyEvent -= value;
    }
} 
In case of VB.NET we have a third block too, for RaiseEvent, which will be invoked whenever some Event is raised from within the code.

Use Using and Try/Catch block for Resource Cleanups

Going like this, It is always better to use Using block whenever you use Disposable Objects. In case of all constructs .NET provides, Try /Catch block and Using block generally calls Dispose() function automatically whenever object which implements IDisposable comes out of the block. Thus use of Try/Catch block and Using block is always better in .NET. See the example below:

public void Execute(string connectionstring, string sql)
{
    SqlConnection con = new SqlConnection(connectionstring);
    SqlCommand cmd = new SqlCommand(sql, con);
    con.Open();
    cmd.ExecuteNonQuery(); 
    cmd.Dispose();
    con.Dispose();
} 


In the above code snippet, we are simply creating an object of SqlConnection and SqlCommand. It is true that both objects implements IDisposable. Thus it is better to rewrite the code like below:
public void Execute(string connectionstring, string sql)
{
     using(SqlConnection con = new SqlConnection(connectionstring))
    {
         using(SqlCommand cmd = new SqlCommand(sql, con))
        {
            con.Open();
            cmd.ExecuteNonQuery(); 
          }
     }
 } 

Thus rewriting like this will automatically call Dispose method, but we dont need to call it directly. Therefore, it is better to make use of Using statement for quick resource deallocation.

You can also use Try/ Catch block similar to this as below
try 
{
    SqlConnection con = new SqlConnection(connectionstring);
    try
    {
        SqlCommand cmd = new SqlCommand(sql, con);
        con.Open();
         cmd.ExecuteNonQuery(); 
    }
    catch {}
    finally
    {
        cmd.Dispose();
    }
    }
    catch(){}
    finally
    {
        con.Dispose();
    }
} 


Next, it is always better to use "as" or "is" rather than casts. Means while we want convert types we should use "as" keyword rather than implicitely typecasting.

object o = new SqlConnection();
SqlConnection con = o as SqlConnection; // Better to use this
SqlConnection con = CType(o, SqlConnection); // Not always better if you dont know the type 


Here as will set the object to null if it cannot cast. So you can check the object to null, and do the job. By this way you are avoiding InvalidCastException and NullReferenceException both.

In the above two statements, if you use the second one for conversion rather than opting for the first, it will throw error if Ctype cannot convert object to that type and also if there is null in o. But in case of using 'as' statement it will not throw error, but rather it will assign null to con.

Use Structure while calling a Function

Good to call functions with small numbers of arguments. Generally it takes a lots of time to send multiple arguments rather than sending a large object directly to the function. Try creating a Structure for all those arguments that you want to send, and send the structure directly. As structures are sent using value type, we can also minimize boxing.

public void Callme(int x, int y, string zy)
public void Callme(argumentStruct st) // Better in performance


Thus it would be always better to send a structure rather than discrete objects. This also leaves out the unnecessarily passing null to the function.

Note : 2010 introduces typed parameters, so my motive is to the users who are using the earlier versions of 2010.


Better to have one Large Assembly rather than having a number of Small Assemblies

Similar to what I have told you earlier, it will be a good practice to have one large assembly with lots of namespaces in it rather than creating a number of small class libraries, one for each namespaces. Even microsoft does this by creating all assemblies within mscorlib.dll, thus reducing load of metadata, JIT compile time, security checks etc. The JIT also uses Reflection to load objects, so if you increase the number of Assemblies, it will make it poorer in performance.

Better to avoid Threading if it is not unavoidable as it leaves out lots of objects into Garbage collection consideration.

Generally use of many threads may lead to lack of performance as each threads takes a lot of memory from the main process to run independently. Is it seem strange to you? Its true. In cases when you need quick processing, you can use threading, but it will increase memory consumption.
Do use of ThreadPool when you create Threads.

Avoid use of ArrayList or HashTables, rather go for Linked Arrays when you need to insert data randomly

Even like you, I am also surprised to say this. Actually, if you see the internal structure of an ArrayList or HashTables, they are just a wrapper of Array. Whenever you insert an object to these structure, it redims all the allocations, and shifts them manually. ArrayList is an Array of objects while HashTable is an Array of Structure.
Another strange thing is, for ArrayList or HashTables, Extents are made in modulus of 4. That means whenever it needs memory it always allocates in a multiple of 4. LinkLists, Generic Lists, LinkedArrays are always better in performance than Collection Objects when you need random insertion. Collections are better when you need to just add data and show data in sequence.

I will talk about memory management more, but need some more experience for writing. Thanks for reading.

You can read a few more about Memory Management in my other blog article  :
http://www.codeproject.com/Articles/38069/Memory-Management-in-NET.aspx

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Abhishek Sur
Architect
India India
Did you like his post?

Oh, lets go a bit further to know him better.
Visit his Website : www.abhisheksur.com to know more about Abhishek.

Abhishek also authored a book on .NET 4.5 Features and recommends you to read it, you will learn a lot from it.
http://bit.ly/EXPERTCookBook

Basically he is from India, who loves to explore the .NET world. He loves to code and in his leisure you always find him talking about technical stuffs.

Presently he is working in WPF, a new foundation to UI development, but mostly he likes to work on architecture and business classes. ASP.NET is one of his strength as well.
Have any problem? Write to him in his Forum.

You can also mail him directly to abhi2434@yahoo.com

Want a Coder like him for your project?
Drop him a mail to contact@abhisheksur.com

Visit His Blog

Dotnet Tricks and Tips



Dont forget to vote or share your comments about his Writing

You may also be interested in...

Comments and Discussions

 
GeneralMy vote of 1 Pin
akjoshi22-May-12 21:41
memberakjoshi22-May-12 21:41 
GeneralMy vote of 1 Pin
Leonardo Paneque24-Apr-12 4:26
memberLeonardo Paneque24-Apr-12 4:26 
QuestionOut of memory exception Pin
NaveenSoftwares29-Jan-12 17:28
memberNaveenSoftwares29-Jan-12 17:28 
GeneralMy vote of 4 Pin
Member 783283412-Oct-11 23:18
memberMember 783283412-Oct-11 23:18 
GeneralFew things I dont agree with you. Pin
ranjan_namitaputra2-Oct-09 11:27
memberranjan_namitaputra2-Oct-09 11:27 
GeneralI don't agree Pin
Johann Gerell27-Jul-09 22:07
memberJohann Gerell27-Jul-09 22:07 
GeneralRe: I don't agree Pin
Abhishek Sur28-Jul-09 22:10
memberAbhishek Sur28-Jul-09 22:10 
GeneralRe: I don't agree Pin
Mel Padden10-Oct-11 0:16
memberMel Padden10-Oct-11 0:16 
GeneralRe: I don't agree Pin
Abhishek Sur11-Oct-11 14:39
mvpAbhishek Sur11-Oct-11 14:39 
GeneralLots of mistakes Pin
S. Senthil Kumar24-Jul-09 5:30
memberS. Senthil Kumar24-Jul-09 5:30 
GeneralCool... It's really helpfull Pin
microsoft_kc16-Jul-09 22:27
membermicrosoft_kc16-Jul-09 22:27 
GeneralRe: Cool... It's really helpfull Pin
Abhishek Sur19-Jul-09 21:25
memberAbhishek Sur19-Jul-09 21:25 
GeneralMy vote of 1 Pin
zitun16-Jul-09 6:04
memberzitun16-Jul-09 6:04 
GeneralToo ambitious Pin
g82942915-Jul-09 3:42
memberg82942915-Jul-09 3:42 
GeneralRe: Too ambitious Pin
Abhishek Sur16-Jul-09 4:43
memberAbhishek Sur16-Jul-09 4:43 
Questionlock? Pin
Tweety12-Jul-09 23:47
memberTweety12-Jul-09 23:47 
GeneralMy vote of 1 Pin
zlezj12-Jul-09 23:42
memberzlezj12-Jul-09 23:42 
GeneralRe: My vote of 1 Pin
Abhishek Sur14-Jul-09 22:05
memberAbhishek Sur14-Jul-09 22:05 

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

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

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.150731.1 | Last Updated 26 Jul 2009
Article Copyright 2009 by Abhishek Sur
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid