views:

703

answers:

3
0:000> !dumpheap -stat
total 1755874 objects
Statistics:
MT    Count    TotalSize Class Name
7b9b0c64        1           12 System.Windows.Forms.Layout.TableLayout+ColumnSpanComparer
....
7933303c    14006      4926456 System.Collections.Hashtable+bucket[]
65246e00      804      4982192 System.Data.RBTree`1+Node[[System.Int32, mscorlib]][]
054c55f0    44240      5662720 DevExpress.Utils.AppearanceObject
793040bc    98823      7613156 System.Object[]
793308ec   293700     55820016 System.String
002435f0    50315    138631888      Free
Total 1755874 objects

Fragmented blocks larger than 0.5 MB:
    Addr     Size      Followed by
15a195c8    0.8MB         15ae3950 System.Collections.ArrayList
15d81468    1.6MB         15f23708 System.String
15f23984    1.0MB         16029ae4 System.String
... about 7 more objects here
1ee51764    0.5MB         1eedbaa4 System.WeakReference
1f0df96c    2.4MB         1f34d4b0 System.String
1f3e1ca8    3.7MB         1f79afc4 System.WeakReference

I've been reading about pinning and fragmentation. Its looking fragmented to me given the massive amount of free space. I guess I have to now track it down.

Thoughts? feedback?

+2  A: 

Is it causing you a problem?

Or are you being like one of those guys who reads about a weird disease on the internet and then convince themselves that they have it?

.NET is memory managed. Usually the answers is if it's causing you pain, look for anything obvious in the code like boxing/unboxing, newing up too many object you don't need etc etc.

Then buy more memory. It's a lot cheaper than development time.

IainMH
I don't fully support the just throw metal at it. But having memory allocated and then freed is normal in .Net Just let it do it's thing (don't forget to clean up unmanged resouces and don't use unsafe/fixed unless you have a real need)
Matthew Whited
Yes, the last bit of the answer was slightly flippant. But then again the OP is a bit "My thumbs have gone weird!" so.. http://www.imdb.com/title/tt0094336/quotes
IainMH
Perhaps I am one of those people, but I enjoy my plastic bubble, no germs can get me in here.I was under the impression that if free space takes up a large portion of the heap, say > 10% then its something to investigate. After an induced garbage collection (for testing) it's still high. Also fraged heaps are apparently more expensive. You can throw more memory at it to a degree, but not in this case. Its a desktop app being deployed to traders desks, they run 32 bit windows, they have the max 4gb ram, they already complain about performance.
Keith
You are Michael Jackson and I claim my £5*. Performance is probably *far* more likely to be across the domain boundaries such as disk i/o and network. Database connections (a nice combination of both) are massivley expensive. Are you making sure they are getting released properly? Using pattern etc (i.e. making sure that Dispose is being called).*http://en.wikipedia.org/wiki/You_are_X_and_I_claim_my_five_pounds
IainMH
Oh really @Weixiao.Fan. You are obviously a douchbag. He didn't say anything about building a "high performance .net application" did he? Learn to play nice or don't bother playing at all.
IainMH
A: 

Since you're using the .NET-Framework everything is fine because the garbage collector will do its magic when appropriate and compact the heap.

See Eric Lipperts great post for a little insight on how the GC works.

VVS
@David - Nice link.
IainMH
Thanks David, I've also read the following links before posting: http://blogs.msdn.com/maoni/archive/2004/12/19/327149.aspx (actually his whole 'Using GC Efficiently' series was great) http://blogs.msdn.com/tom/archive/2008/02/18/high-memory-part-5-fragmentation.aspx https://blogs.msdn.com/yunjin/archive/2004/01/27/63642.aspx Also tess has lots of general windbg stuff http://blogs.msdn.com/tess
Keith
Another good link here: http://stackoverflow.com/questions/686950/large-object-heap-fragmentation Ok, I'll keep investigating. 130 mb of free space, then 90mb after a GC looks odd to me. Granted, it may be nothing.
Keith
Another good link talking about fragmentation: http://msdn.microsoft.com/en-us/magazine/cc163528.aspx#S8
Keith
+1  A: 

So...we know we have a fragmented heap. The next question is: what's causing the fragmentation? What's keeping these free objects from being released? The recommendations I have read is to examine the objects right after the free space:

1) !dumpheap -stat 2) Dump the method table of the Free object: !dumpheap -mt 000db8e8 3) Select one Free object from the list to examine more closely: !dumpobj 0x2003b0b0 4) Record the object's size 5) Dump the next object after it: !dumpobj 0x2003b0b0+1000 6) Find the object holding a reference !gcroot 0x2003b0b0+1000 7) Dump the gchandle of the object found.

I usually get down this rabbit hole, and my limited knowledge of the .NET API fails here. Is this the correct way to debug the problem?

Jeff

I've had a look at which heap is fragmentation. I initially used !eeheap -gc to get a basis for the segments to search, however SOSEX (http://www.stevestechspot.com/SOSEXV2NowAvailable.aspx) has some commands just for this. Its looking like its in the Large object heap (which is expected as its never compacted) and to some degree in the gen2 heap. gen0 I don't care about and gen1 has no fragmentation. I think what your saying is try figure out the objects that are assigned after the fragmentation then work back from there to see whats causing the fragmentation, i.e. !dumpobj 0x2003b0b0+1000
Keith