+1  A: 

Are you sure you have a memory leak? The .NET Compact Framework garbage collector works slightly differently to the one in the full .NET framework. From Steven Pratschner's blog:

A collection is initiated when either:

  • 1MB of objects have been allocated,

  • An application is moved to the background,

  • A failure to allocate memory occurs

  • An application calls GC.Collect.

Mitch Wheat
Hi Mitch, I read Steven's blog and can confirm that these objects are not freed, even after: Calling GC.Collect() or allocating more than 1MB of objects
Philip Fourie
A: 

You've probably seen this already; according to Steven Pratschner:

The best way to track the amount of memory used to store objects in the GC heap is to monitor the "Managed Bytes in use After GC" counter in RPM. Graphing the value of this counter over time using Perfmon is the easiest way to determine whether the heap is continually growing.

Have you tried monitoring that counter?

Mitch Wheat
Hi Steven. Thanks for the information I didn't know that (I am new to RPM). I quickly did another test using this counter, although it reacts differently it also keep climbing (seems like it is allocating chunks of memory when nearing the previous allocated limit)
Philip Fourie
What version and service pack of the CF are you on?
Mitch Wheat
+2  A: 

A Form does not automatically Dispose all Controls created in its code, as it has no way to know it exists. To get the Form to Form to Dispose it automatically when it's Disposed, you need to add it to the Controls collection.

Now in your case that may not do anything. I can't tell if your example is contrived, or real world. If it's real-world, then the behavior is expected, as the Panel doesn't get collected when the variable goes out of scope (not sure it does on the desktop either). It becomes available for collection, but that simply means that on the next collection pass it will be swept. Unless you're causing a GC, then it's not going to be freed.

I'd highly recommend you take a look at the MSDN webcast on memory management in the CF. It provides a much more thorough explanation as to what's happening under the hood - far more than we could provide in an answer here.

ctacke
A: 

@ctacke, thanks for the feedback it is much appreciated.

  1. I tried watching the web cast but the URI gives an error. (I'll try again later)
  2. Calling GC.Collect() still doesn't clean up the created panels. (However on the desktop it does).
  3. This is a simplified example, in the real app controls are added and removed from the form's control collection based upon user input. Unfortunately after a control is removed from the Form Control collection it will not be disposed when the forms closes (but rather when the application closes!) I can't call Dispose() on the object at time of removing from the Form Control Collection as some other objects might still have reference to it.

I was hoping that the execution behaviour would be the same of Windows Forms (that is, when all references to an object have been removed the GC will free it at the next run)

Philip Fourie
Just out of curiosity: why do other objects (presumably not at the form level) still have references to a control on your form? This seems to go around the encapsulation principle.
MusiGenesis
+3  A: 

Some additional information here that explains this behaviour.

According to Ilya Tumanov:

Everything UI related on NETCF is intentionally removed from GC scope so it is never collected. This behavior is different from desktop and has been changed in NETCF V3.5 (unless running in compatibility mode).

It is so different because managed UI classes on NETCF are completely different from desktop. They are thin wrappers over native implementation which was needed to achieve acceptable performance.

I’m not sure there’s such a resource. But really, all you need to know is: it’s never collected, must call dispose. You actually should do that on desktop as well but if you don’t its way more forgiving. Not so on NETCF.

Philip Fourie
A: 

Is there any solution for the problem? I think that I have the same problem with VS 2003 an CF 1.0 SP 3 on Mobile2003 and Mobile5.0.

Can anyone help?

There is no "solution" becasue I don't believe there's a problem. The behavior is by design. If you're dynamically creating controls, you should be reusing them, not just infinitely generating them.
ctacke
+1  A: 

I think you need to dynamically remove the Button Click EventHandler too, as you can see from this blog : http://blogs.msdn.com/stevenpr/archive/2007/03/08/finding-managed-memory-leaks-using-the-net-cf-remote-performance-monitor.aspx

It is from Steven Pratschner too.

By the way, the webcast mentioned above is linked here: http://msevents.microsoft.com/cui/WebCastEventDetails.aspx?culture=en-US&EventID=1032318791&CountryCode=US

Hope this helps!