What's the deal with declaring something static

We have a few customer who are using statics and not really understanding what they are creating.  There is a very good explanation at:
http://msdn2.microsoft.com/en-us/library/98f28cdx(VS.71).aspx

The summary of the important parts of that are:

  1. Use the static modifier to declare a static member, which belongs to the type itself rather than to a specific object.
  2. A static member cannot be referenced through an instance.
  3. While an instance of a class contains a separate copy of all instance fields of the class, there is only one copy of each static field.
  4. To demonstrate instance members, consider a class that represents a company employee. Assume that the class contains a method to count employees and a field to store the number of employees. Both the method and the field do not belong to any instance employee. Instead they belong to the company class. Therefore, they should be declared as static members of the class.

So now lets talk about the common mistake that is made.  First we create a class like:

public class MyClass
{
    public static Dictionary myDictionary;
    MyClass()
    {
        
    }
}

Let's say we create the MyClass object, when we have a user hit a page on our site.  And we are going to store some data in the dictionary, say 10 items.  We add our information and then after we are done with the class, we do something like MyClassObj = null to get rid of the object.

The important thing to note here is #3 above, so even though your object goes away, the static members stay around.  So the next time the page is hit, we will add 10 more items to the existing dictionary and this will continue and the dictionary will grow.

Troubleshooting

So how does this end up looking in the debugger?  Well we will see a lot of strings or whatever the object type is that is being stored in the Dictionary on the heap and then we can use !gcroot to try see why this object is still around, and what will will find is something like:

DOMAIN(00174428):HANDLE(Pinned):49911f0:Root:  28054110(System.Object[])->
  1c16f0f0(System.Collections.Generic.Dictionary`2[[System.Int32, mscorlib],
[System.Collections.Generic.List`1[[System.ServiceModel.ICommunicationObject
, System.ServiceModel]], mscorlib]])-> 2c0c00a8(System.Collections.Generic.Dictionary`2+Entry[[System.Int32,
mscorlib],[System.Collections.Generic.List`1[[System.ServiceModel.
ICommunicationObject, System.ServiceModel]], mscorlib]][])-> 1855d6e4(System.Collections.Generic.List`1[[System.ServiceModel.
ICommunicationObject, System.ServiceModel]])-> 1855d6fc(System.Object[])-> 1854a5f8 ... 1854f1a8(System.Collections.Generic.Dictionary`2+Entry[[System.Type,
mscorlib],[System.ServiceModel.Description.ContractDescription, System.
ServiceModel]][])-> 1854a704(System.ServiceModel.Description.ContractDescription)-> 1854a77c(System.ServiceModel.Description.OperationDescriptionCollection)-> 1854a78c(System.Collections.Generic.List`1[[System.ServiceModel.
Description.OperationDescription, System.ServiceModel]])-> 1854d5c8(System.Object[])-> 1854d0c4(System.ServiceModel.Description.OperationDescription)-> 1854d134(System.ServiceModel.Description.MessageDescriptionCollection)-> 1854d144(System.Collections.Generic.List`1[[System.ServiceModel.
Description.MessageDescription, System.ServiceModel]])-> 1854d458(System.Object[])-> 1854d4b0(System.ServiceModel.Description.MessageDescription)-> 1854d248(System.String)

As you can see from this, there is no easy way to tell where this dictionary is coming from or what we should do about it.  Sometimes we can get lucky and find it while it is being added to, but that would be lucky.  Other then that, all we can do is look at the data inside it and try to tell what it is from that.  The best solution is to understand what you are creating and how it will be handled by .NET so you don't get into a situation like this.

Additional Static References:
http://www.ondotnet.com/pub/a/dotnet/2003/07/07/staticxtor.html

Published 07 December 07 04:25 by Tom
Filed under: , ,

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

# MSDN Blog Postings » What's the deal with declaring something static said on December 7, 2007 4:47 PM:

PingBack from http://msdnrss.thecoderblogs.com/2007/12/07/whats-the-deal-with-declaring-something-static/

# Jas said on February 23, 2009 5:25 PM:

In my case Cx is knowing they are storing 250,000 Dictionary object . All seemed to be Pinned

DOMAIN(001097E8):HANDLE(Pinned):29313f8:Root:  1296aad8(System.Object[])->

 0e97e7e4(System.Collections.Generic.Dictionary`2[[System.Int32, mscorlib],XXXXXX]])->

 13a9cde8(System.Collections.Generic.Dictionary`2+Entry[[System.Int32, mscorlib],[XXXXXXX]][])->

 03d3d36c(XXXXXX.BlockListItem)->

 03d3f01c(XXXXXX)->

 03d3ee40(System.String)

Which is causing memory to fragment and Frequent GC to kick in.

Any Suggestions?

Thanks

# Tom said on February 24, 2009 10:36 PM:

Are they pinning the dictionary object?  Using native memory?  or is the root string longer then that?

Generally pinning should be used when using native memory.

Leave a Comment

(required) 
(optional)
(required) 

  
Enter Code Here: Required

Search

This Blog

Page view tracker