Thread handle leak

G

Guest

I have a question regarding garbage collection for threads. I am currently
developing on Visual Studio 2003 on .NET Framework 1.1. When I run this
simple app and watch the Handle count in Task Manager, the handle count keeps
increasing every time a new thread starts. If I uncomment the line
//GC.Collect();, handle count stabilizes after a moment.

Next I threw the same code onto VS2005 on .NET Framework 2.0, with
GC.Collect(); REM'ed out, the handle count also stabilizes after a moment,
but with GC.Collect(); the handle count stabilizes at a much lower count
compared to it being REM'ed out.

My questions are:
1. Is there a known issue with .NET 1.1 not able to garbage collect on
threads?
2. From the posts I read, GC should automatically kick in to do cleanup. So
then, should I manually perform a GC?

Code:

private void Form1_Load(object sender, System.EventArgs e)
{
TestThread();
}

private void TestThread()
{
lbl_Time.Text = DateTime.Now.ToString();
gtTimerThread = new Thread(new ThreadStart(TimerThreadProc));
gtTimerThread.Start();
//GC.Collect();
}

private void TimerThreadProc()
{
Thread.Sleep(1000);

this.Invoke(gtdTestThread);
}
 
W

Willy Denoyette [MVP]

FourLow said:
I have a question regarding garbage collection for threads. I am currently
developing on Visual Studio 2003 on .NET Framework 1.1. When I run this
simple app and watch the Handle count in Task Manager, the handle count
keeps
increasing every time a new thread starts. If I uncomment the line
//GC.Collect();, handle count stabilizes after a moment.

Next I threw the same code onto VS2005 on .NET Framework 2.0, with
GC.Collect(); REM'ed out, the handle count also stabilizes after a moment,
but with GC.Collect(); the handle count stabilizes at a much lower count
compared to it being REM'ed out.

My questions are:
1. Is there a known issue with .NET 1.1 not able to garbage collect on
threads?
2. From the posts I read, GC should automatically kick in to do cleanup.
So
then, should I manually perform a GC?

Code:

private void Form1_Load(object sender, System.EventArgs e)
{
TestThread();
}

private void TestThread()
{
lbl_Time.Text = DateTime.Now.ToString();
gtTimerThread = new Thread(new ThreadStart(TimerThreadProc));
gtTimerThread.Start();
//GC.Collect();
}

private void TimerThreadProc()
{
Thread.Sleep(1000);

this.Invoke(gtdTestThread);
}

What makes you think it's a "thread" handle leak? Do you notice an increase
of the OS threads in taskman, if not, they are no thread handles but other
object handles.

Willy.
 
P

Peter Huang [MSFT]

Hi

Have you tried Willy's suggestion?
What is the result on your machine.


Best regards,

Peter Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.
 
G

Guest

I'm not very sure what is meant by OS threads. Is it a certain process in the
task manager that I should look at? Could you help clarify that a bit?

The reason I thought it's the thread is because when I debug it and put a
breakpoint right at the gtTimerThread.Start(), as soon as that line of code
executes, the handle count for that app increases, judging from what I saw in
task manager.
 
P

Peter Huang [MSFT]

Hi

The OS threads means the unmanaged Win32 Thread(created by CreateThread),
actually the .NET will also call the API to create managed thread, commonly
a managed thread will have a corresponding win32 thread.
When you open the taskmanager, and select the Processes tab, it list the
running process.
You may select the process you want to check and note that it has a few
column.
e.g. ImageName,PID,User name......., Threads
The Threads account is what you need to monitor. It means how many win32
threads(i.e. OS Threads) is running.

From your description,
"If I uncomment the line
//GC.Collect();, handle count stabilizes after a moment."

Because if there is a handle leak, the thread count will be increasing. And
every thread should have a thread handle, so if you want to check the thead
handle leak, you need to check the threads column in the taskmanager.

Also we consider the scenario has handle leaking that in the app running
time, the handle will keep growing even crash the application. But from
your description,
"If I uncomment the line
//GC.Collect();, handle count stabilizes after a moment."
It seems that it will be stabilized.

Also commonly we did not suggest call GC.collect directly in your
application, because .NET runtime have a full optimized GC and has its own
implement algorithm to make the application running smoothly. So .NET 2.0
and .1.1 use different GC so will have different behavior, also the .NET
2.0 class is not same as .NET 1.1. class so the whole application running
environment is different. Every time GC running, it will consume CPU time,
so the CLR has a optimized algorithm when and how to do that. That is why
we did not suggest you call GC.Collect directly in your code.


Best regards,

Peter Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top