Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WeakReferences are not freed in embedded OS

I've got a strange behavior here: I get a massive memory leak in production running a WPF application that runs on a DLOG-Terminal (Windows Embedded Standard SP1) that behaves perfectly fine if I run it localy on a normal desktop (Win7 prof.)

After many unsucessful attempts to find any problem I put one of those directly beside my monitor, installed the ANTs MemoryProfiler and did one hour test run simulating user operations on both the terminal and my development PC.

Result is, that due to some strange reasons the embedded system piles up a huge amount of WeakReference and EffectiveValueEntry[] Objects.

Here are are some pictures:

Development (PC): enter image description here

enter image description here

And the terminal: enter image description here

Just look at the class list... enter image description here

Has anyone seen something like this before and are there known solutions to this? Where can I get help?

(PS the terminals where installed with images prepared for .net4)

PPS: for the close-voter: I think the question is clear: how can I fix this. You could argue if this is a IT/OS problem vs. a programming problem but I think if I post this in Server Fault it will get a off-topic close in no time...

UPDATE: I was able to find a big portion of the problem - but it feels a bit like C++: I use a ViewModel-like Items class for a WPF-List that provides (among others) a ICommand (RelayCommand-pattern). The Items where created on the fly in the getter of a ViewModel-Property for the view and it seems that the application/GC did never free those unused commands - or the subscribtions to their CanExecuteChanged - the memory profiler shows those as "held by a weak reference". I changed my code to reuse those item-viewmodels and Dispose/set to null every used properties in their Dispose and use this too as clean up - as I said: feels like "delete" in those old C++ days. On top of this I use a forced GC.Collect every 30mins (yeah I know - you never should - but I got no other solution till now). With this setup the applications runs for 6+ hours without problems so far but it don't feel right.

I cannot understand why those WeakReferences are not claimed as they are on my desktop machine...

Any thoughts on this? Please!

UPDATE: I am still not able to pin down this problem but I see a strange behavior: If I use PC-Anywhere to observe the operation of my software on one of the terminals the problem goes away! Even after running 8hr. straight the software runs as it should - it will even free memory (I put a little memorycounter-display in the main-screen - let's say I connect to the terminal and see that memory is low - after waiting a few minutes the memory is reclaimed)

So I think Devin (one Answer below) has a lead in the right direction - something in the Remote-Control software unblocks the finalizer-thread or whatever is blocking the GC - be it the simulated keyboard/mouse or whatever.

Any thoughts on this?

like image 599
Random Dev Avatar asked Apr 16 '12 11:04

Random Dev


2 Answers

We had a (somewhat) similar issue running my app on a tablet. The memory would be reclaimed when run on a desktop, but not when run on a tablet or some other device that used a PC Input panel. The problem is that the finalization queue was getting stuck. The COM object finalizer was waiting to run something on the main thread, which didn't have a message loop.

The solution was to find an adequate time to invoke Application.DoEvents(). We had a method that would be called intermittently and we invoke it with every 10th call. I don't know if this is the same issue you are having, but maybe it can shed some light.

EDIT: I do need to make it clear, in general, calling DoEvents() is a bad idea. It works in that case because there isn't any UI on that thread or anything else happening that those events can interfere with.

like image 91
Devin Avatar answered Sep 30 '22 09:09

Devin


From the screenshots it is interesting to see that the LOH grows at the same time the used space does not grow much. The free space is growing a lot at the LOH which indicates memory fragmentation due to pinned objects. This looks like a stuck finalizer thread which does prevent the cleanup of managed objects. You should get a memory dump and check in which method the finalizer thread was stuck. You can do this quite easy with Windbg.

like image 24
Alois Kraus Avatar answered Sep 30 '22 10:09

Alois Kraus