views:

729

answers:

3

I have a feeling that I'm putting rather much data in my ASP.NET session, but I've no idea how much and if I should be concerned. I found a similar question, but that relies on serializing objects and checking their serialized size. In my case the majority of data in the session is in objects from another library which doesn't have its classes marked as "Serializable". (I know that this restricts me to using InProc session state provider, but that's another issue). Does anyone have an idea on how to traverse the object graph and find out its size?

Added: OK, one way would be a manual traversal of the object graph and usage of Marshal.SizeOf() method. But that's a lot of writing to get that working. Is there perhaps a simpler way of achieving the same effect? I'm not aiming for byte precision, I'm interested in the order of magnitude (kilobytes, megabytes, tens of megabytes...)

A: 

You can probably store the session state information in the database and check the size, but I am not sure if there is any tool out there that can let you view and traverse the object graph.

If possible, check your design one more time to see if you can minimize the information in the session.

CodeToGlory
Read carefully! Somewhere in there, written in small print, there is a word or two about "non-serializable objects". I can't convert it to a byte stream, much less put it in a DB!
Vilx-
And as for memory optimizations - the code is already as minimalistic as I could make it without resorting to "tricky, clever optimization tricks". I might be able to squeeze it more, but that would come at a great effort. I want to find out if it's worth it.
Vilx-
Hi Vilx, can you give me more information on non-serializable objects?
CodeToGlory
+1  A: 

For testing, you could put together a stub Custom Session provider, implementing the SessionStateStoreProviderBase abstract class. I would write backing fields that stash everything in WebCache (so that you have session data managed), and eventually generate a statistic using the Marshal.SizeOf() method when the SetAndReleaseItemExclusive method is called.

     public override void SetAndReleaseItemExclusive(HttpContext context, string id, SessionStateStoreData item, object lockId, bool newItem)
     {

        double MemSize = 0;
        foreach (object sessObj in item.Items)
        {
            MemSize += Marshal.SizeOf(sessObj);
        }

}

Consult this question for more information on getting field size: http://stackoverflow.com/questions/207592/getting-the-size-of-a-field-in-bytes-with-c

Jeff Fritz
http://msdn.microsoft.com/en-us/library/y3ybkfb3.aspx - "This method accepts an instance of a structure, which can be a reference type or a boxed value type. The layout must be sequential or explicit."
meandmycode
Doesn't that just give me the size of one object, not the whole graph? The problem is, I don't put simple objects in the session. There are whole DataTables there (or rather, classes derived from DataTable). And one item may be found under several keys in the session.
Vilx-
Right, you're going to need to traverse your object graph in order to accurately calculate the size of an object, since you cannot serialize. For that, you will need to do some heavy recursive reflection work. This gets you analysis of session size outside of a page structure
Jeff Fritz
+1  A: 

can't you generate a heap dump and find the size of the session from that. in java land i can dump the heap then open it up in mat, find the session object and find out the size of the subgraph.

drscroogemcduck
Not without 3rd party tools I can't... But it's an idea. I've used ".NET Memory Profiler" before, and it was good. Maybe it could help in this case as well.
Vilx-