Memory Leak
-
Every software developer likes analysing memory leaks, don't we? :~ Last friday, I had to work on such a thing. After interacting with a different machine, our WPF application allocated some 100 MB per second, and there is no machine which will stand that for a reasonable time span. The interaction with that other machine is via WCF. Since some hardware actions take time, I implemented it as a Task. Sometimes, the hardware failed and raised an exception. Our WCF implementation failed to cope with the faulted task. An UnobservedTaskException was raised instead (see also Unobserved TaskException[^] ). The exception handler still assumed .Net 4 behavior: that the application is about to crash now. It logged the exception, and then showed a MessageBox with the exception details, but that MessageBox hid behind the main window of the application becoming invisible for the user. And now the memory leak started... Why? Well, the handler of the Unobserved TaskException runs in the Finalizer thread. The MessageBox is modal. I.e. the MessageBox blocks the thread of the Garbage Collection required for unmanaged memory cleanup... Some things go terribly wrong.
Oh sanctissimi Wilhelmus, Theodorus, et Fredericus!
-
Every software developer likes analysing memory leaks, don't we? :~ Last friday, I had to work on such a thing. After interacting with a different machine, our WPF application allocated some 100 MB per second, and there is no machine which will stand that for a reasonable time span. The interaction with that other machine is via WCF. Since some hardware actions take time, I implemented it as a Task. Sometimes, the hardware failed and raised an exception. Our WCF implementation failed to cope with the faulted task. An UnobservedTaskException was raised instead (see also Unobserved TaskException[^] ). The exception handler still assumed .Net 4 behavior: that the application is about to crash now. It logged the exception, and then showed a MessageBox with the exception details, but that MessageBox hid behind the main window of the application becoming invisible for the user. And now the memory leak started... Why? Well, the handler of the Unobserved TaskException runs in the Finalizer thread. The MessageBox is modal. I.e. the MessageBox blocks the thread of the Garbage Collection required for unmanaged memory cleanup... Some things go terribly wrong.
Oh sanctissimi Wilhelmus, Theodorus, et Fredericus!
I've once managed to create a memory leak in Mono by creating an object in an event handler and using the object in another event handler. Worked fine in .NET, ran over on RPi in Mono. Granted, the code hasn't been clear to begin with.
-
Every software developer likes analysing memory leaks, don't we? :~ Last friday, I had to work on such a thing. After interacting with a different machine, our WPF application allocated some 100 MB per second, and there is no machine which will stand that for a reasonable time span. The interaction with that other machine is via WCF. Since some hardware actions take time, I implemented it as a Task. Sometimes, the hardware failed and raised an exception. Our WCF implementation failed to cope with the faulted task. An UnobservedTaskException was raised instead (see also Unobserved TaskException[^] ). The exception handler still assumed .Net 4 behavior: that the application is about to crash now. It logged the exception, and then showed a MessageBox with the exception details, but that MessageBox hid behind the main window of the application becoming invisible for the user. And now the memory leak started... Why? Well, the handler of the Unobserved TaskException runs in the Finalizer thread. The MessageBox is modal. I.e. the MessageBox blocks the thread of the Garbage Collection required for unmanaged memory cleanup... Some things go terribly wrong.
Oh sanctissimi Wilhelmus, Theodorus, et Fredericus!
-
Every software developer likes analysing memory leaks, don't we? :~ Last friday, I had to work on such a thing. After interacting with a different machine, our WPF application allocated some 100 MB per second, and there is no machine which will stand that for a reasonable time span. The interaction with that other machine is via WCF. Since some hardware actions take time, I implemented it as a Task. Sometimes, the hardware failed and raised an exception. Our WCF implementation failed to cope with the faulted task. An UnobservedTaskException was raised instead (see also Unobserved TaskException[^] ). The exception handler still assumed .Net 4 behavior: that the application is about to crash now. It logged the exception, and then showed a MessageBox with the exception details, but that MessageBox hid behind the main window of the application becoming invisible for the user. And now the memory leak started... Why? Well, the handler of the Unobserved TaskException runs in the Finalizer thread. The MessageBox is modal. I.e. the MessageBox blocks the thread of the Garbage Collection required for unmanaged memory cleanup... Some things go terribly wrong.
Oh sanctissimi Wilhelmus, Theodorus, et Fredericus!
I once spent close to three months eliminating leaks from a C#/WPF application. There were basically two sources of leaks. One were the false optimizations I had done as a matter of course due to my prior experience as a C++ programmer. I tended to cache resources, which caused them to leak event handlers and such. I also found that data bindings constructed in code rather than XAML leaked, and had to be cleared manually when you were done. The second were the WPF flow document and page navigation mechanisms. Both of them leaked horribly - several megabytes per operation. I replaced them with HTML/WebBrowser (which leaks, but much less) and a home-grown navigation mechanism. When I thought I had all of the leaks figured out, I ran the app over a four day weekend with a tiny test driver that navigated randomly through the UI every couple of seconds. When I came in, the app was still running and had peaked at 400MB, which wasn't bad considered it took up 275MB just starting up. All of the leaks were attributable to the WebBrowser control. Many thanks to the folks at SciTech Software for .NET Memory Profiler.
Software Zen:
delete this;
-
Every software developer likes analysing memory leaks, don't we? :~ Last friday, I had to work on such a thing. After interacting with a different machine, our WPF application allocated some 100 MB per second, and there is no machine which will stand that for a reasonable time span. The interaction with that other machine is via WCF. Since some hardware actions take time, I implemented it as a Task. Sometimes, the hardware failed and raised an exception. Our WCF implementation failed to cope with the faulted task. An UnobservedTaskException was raised instead (see also Unobserved TaskException[^] ). The exception handler still assumed .Net 4 behavior: that the application is about to crash now. It logged the exception, and then showed a MessageBox with the exception details, but that MessageBox hid behind the main window of the application becoming invisible for the user. And now the memory leak started... Why? Well, the handler of the Unobserved TaskException runs in the Finalizer thread. The MessageBox is modal. I.e. the MessageBox blocks the thread of the Garbage Collection required for unmanaged memory cleanup... Some things go terribly wrong.
Oh sanctissimi Wilhelmus, Theodorus, et Fredericus!
This may not address your issue, but I address memory leaks as a preventive process, and have done so going back to VB6 days. In short, I clean up my resources and objects before I allow an instance of a class to go away. In C#, I almost ALWAYS use try-catch-finally. I declare an object as null before "try", instantiate it in the try code block, catch any exceptions (a whole other discussion), then clean up my objects in the finally block. If they have a Dispose or Clear method, I execute that then set the variable to null. No waiting on the GC or coding shortcuts like "using" that get compiled as try-catch-finally anyway. If my class has an class-level objects, I use my Dispose template that also includes the finalizer. Since taking this approach years ago (which is mostly copy and paste snippets), the little added effort has helped me to have zero memory leaks, and as an added bonus (that "catch" thing again), I get excellent debugging info. Sometimes consistency in how we code eliminates a lot of problems later.
-
This may not address your issue, but I address memory leaks as a preventive process, and have done so going back to VB6 days. In short, I clean up my resources and objects before I allow an instance of a class to go away. In C#, I almost ALWAYS use try-catch-finally. I declare an object as null before "try", instantiate it in the try code block, catch any exceptions (a whole other discussion), then clean up my objects in the finally block. If they have a Dispose or Clear method, I execute that then set the variable to null. No waiting on the GC or coding shortcuts like "using" that get compiled as try-catch-finally anyway. If my class has an class-level objects, I use my Dispose template that also includes the finalizer. Since taking this approach years ago (which is mostly copy and paste snippets), the little added effort has helped me to have zero memory leaks, and as an added bonus (that "catch" thing again), I get excellent debugging info. Sometimes consistency in how we code eliminates a lot of problems later.
In C#, I almost ALWAYS use try-catch-finally.
That's the "Padre Nostro" of alldays. :laugh: