Memory Leak using EnumThreadWindows

  • Thread starter Thread starter Lighto26
  • Start date Start date
L

Lighto26

Guest
Hey,

I experience something weird when using EnumThreadWindows

I have this code:

class Program
{
public delegate bool EnumWindowProc(IntPtr hWnd, IntPtr lParam);

[DllImport("user32", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool EnumThreadWindows(int threadId, EnumWindowProc callback, IntPtr lParam);

static void Main(string[] args)
{
var a = true;
while (a)
{
foreach (var process in Process.GetProcesses())
{
foreach (ProcessThread thread in process.Threads)
{
var list = new List<IntPtr>();
EnumThreadWindows(thread.Id, (wnd, param) =>
{
list.Add(wnd);
return true;
}, IntPtr.Zero);
thread.Dispose();
}

process.Dispose();
}

GC.Collect();
Thread.Sleep(1);
}

GC.Collect();
Console.WriteLine("End");
Console.ReadLine();
}
}

When I run this code I can clearly see that my unmanaged memory keep increasing without ever decreasing, even if I stop the while loop and wait, the program's unmanaged memory never decrease

DotMemory screenshot: i.stack.imgur.com/0KlLW.png

So I tried to change my code to use GCHandle.Alloc to pass the list like this:

foreach (ProcessThread thread in process.Threads)
{
var list = new List<IntPtr>();
var aloc = GCHandle.Alloc(list);
var lParam = GCHandle.ToIntPtr(aloc);
EnumThreadWindows(thread.Id, (wnd, param) =>
{
var list1 = GCHandle.FromIntPtr(param).Target as List<IntPtr>;
list1?.Add(wnd);
return true;
}, lParam);
thread.Dispose();
aloc.Free();
}
process.Dispose();
}

When I use GCHandle.Alloc I don't have any memory issues anymore:

i.stack.imgur.com/dga8N.png

The thing is I want to understand why this is happening?

My only idea is that maybe the code inside the EnumWindowProc is unmanaged and when I pass List<IntPtr> which is managed object to the unamanged code it becomes unmanaged and the GC can't clear it anymore.

I may be lacking some understanding of something fundamental so I'd like any explanation :)

Thanks!

Edit: Sorry about the links for some reason I can't insert links because I need to verify my account, and I already did (Also can't find option to send the email again)

Continue reading...
 
Back
Top