views:

107

answers:

3

My application's performance deteriorate as it continues to run through the day.

I suspect it is garbage collector, how can I verify this? Is there a way to find out which object/function is causing garbage collection overhead?

Is there a way to manually perform garbage collection programatically to clear memory of leakages?

Thanks,

edit On one end of the application it receives call back from a unmanaged api to accept data, processes it and then send messages out of socket on the second end. From the second end it then gets back follow up data on the messages it sent out. The application opens 5-6 sockets to send and receive data from the second end. It constantly logs lots of data to windows file system on a separate thread.

My measurements include timestamping (queryperformance counter) just before I send data out and the timestampinga again when I receive the followup from another process back on the socket. I noticed out of multiple sockets I open, the performance deterioration is happening on one socket connection only.

The processing between the timestamping and sending.receiving data over socket includes iterating through 2 arraylist that has no more than 5-6 objects and couple of callbacks.

The memory usage from Task MAnager window does not go up considerably. From 96MB to 100MB after 6-7 hours run.

Following are some observations from running perfmon.

"finanlization survivors" and "promoted finalization memory from Gen 0" gradually increase with time

"Gen 0 collections" going from 1819 at the start to 6000 after 4 hours. "Gen 1 Collections" is 10%-12% of Gen 0 collection and "Gen 2 collection" is 1% or less. COnsidering Gen 0 collection numbers are cumulative, it is probably not abig concern.

GC handles" went up from 850ish to 4000.

+4  A: 

It's far more likely that you have a memory leak, and invoking the GC manually will not help that: it can't dispose of objects if your code hasn't released them.

Edit

Since your GC handles are increasing, this page suggests that there are non-managed resources that are not getting freed. I've had this happen with bitmaps, for example, but you might have to tell us a lot more about your application to get a more specific suggestion.

Here's a thread that may give you some useful insight.

egrunin
Will I see "memory usage" going up in the "Task Manager" window for the process if there is a memory leakage?
bsobaid
Yes, if there's enough to care about you definitely will.
egrunin
so the memory usage only went up from 96MB to 100MB.
bsobaid
Performance counter shows "Gen 0 collections" going from 1819 at the start to 6000 after 4 hours. The "Gen 1 Collections" is 10%-12% of Gen 0 collection and "Gen 2 collection" is 1% or less.
bsobaid
"GC handles" went up from 850ish to 4000. Is there any other counter I should look for?. Do adding counters cause overhead?
bsobaid
I did some further investigation into the problem and found some additional details. The application opens 4-5 socket connections and I am noticing the performance deterioration is attached with traffic coming from one specific socket. I ran wireshark and found that data in and out of the socket remains at a steady rate just somehow my application is processing them slow.
bsobaid
I measure application performance by logging queryperformancecounter before I send out socket and after I receive a corresponding acknowldge message back in the socket. In both cases I do some processing before doing the timestamp logging. The processing include some callbacks and 2 arraylist lookups. The objects in arraylist are added and remove however on average, there are no more than i-e 5 to 10 objects at a given time.
bsobaid
so I ran some more perfmon and found that "finanlization survivors" and "promoted finalization memory from Gen 0" gradually increase with time. What to do about it ?
bsobaid
Please append some details to your question, telling us a little about what your app does (how it interacts with the user, the screen, the filesystem) and what external resources it depends on.
egrunin
+4  A: 

You can call GC.Collect() to force the garbage collection, but this will not fix memory leaks. Try a memory profiler like ANTS memory profiler to find memory leaks.

ANTS memory profiler

Rauhotz
Generally calling `GC.Collect()` is a bad idea, as the Garbage Collector generally does a better job than you (or the developer) can do
PostMan
For certain specialized needs, however, like independent COM servers, it's the only way to govern reference lifetime as it needs to be governed.
Mike Burton
Also if you are setting a lot of temporary things in memory in order to perform actions on them, then storing the results, calling `GC.Collect()` will help if the loops are fast enough. I've had OOM issues because GC wasn't happening fast enough, but I had to do profiling to know that that would actually help me out.
KallDrexx
+2  A: 

It may not necessarily be a memory problem. Use the Windows Performance Monitor (look in administrative tools) to monitor your app's CPU, Memory, GDI object count, handle count, and see if any of these appear to be climbing throughout the life of your app.

Often, you'll find that you're using something from System.Drawing and not calling Dispose() on it, causing a handle leak. I've found that handle leaks tend to eat performance much faster than memory leaks. And handle leaks cause no GC pressure, meaning you could be leaking handles like a sieve and the GC wouldn't ever know the difference.

So, long story short: measure, measure, measure. Then you'll know what to fix.

FMM
+1 on the leaks from the system.drawing namespace.
JoshRoss
does adding counters in perfmon cause performance overhead?
bsobaid
@bsobaid: Doubtful that it would cause appreciable overhead. You're already suffering performance problems, you might as well spend a day measuring to discover the source of the problem.
FMM