hirop
asked on
Memory leak in CWinThread?
I'm experiencing a memory leak when running a thread. I've trimmed it down to the following code:
for (ii = 0; ii < 1000; ii++) {
CWinThread *pWinThread;
pWinThread = AfxBeginThread(ThreadLBPro c, NULL);
::Sleep(500);
}
UINT ThreadLBProc(LPVOID pParam)
{
return 0;
}
I know the 0.5 second sleep is crude, but I believe the thread terminates well within that time. I don't use this technique in the production code!
I appear to be losing about 160 bytes each time the thread is run, or about 160k after 1000 times around the loop. This figure of 160k is obtained from the 'Heap Usage' field in the Process Viewer utility.
I believe that the CWinThread, as I'm currently using it, should auto-delete when the thread terminates.
Any suggestions would be welcome!
for (ii = 0; ii < 1000; ii++) {
CWinThread *pWinThread;
pWinThread = AfxBeginThread(ThreadLBPro
::Sleep(500);
}
UINT ThreadLBProc(LPVOID pParam)
{
return 0;
}
I know the 0.5 second sleep is crude, but I believe the thread terminates well within that time. I don't use this technique in the production code!
I appear to be losing about 160 bytes each time the thread is run, or about 160k after 1000 times around the loop. This figure of 160k is obtained from the 'Heap Usage' field in the Process Viewer utility.
I believe that the CWinThread, as I'm currently using it, should auto-delete when the thread terminates.
Any suggestions would be welcome!
Listening...
sounds interesting
Dear hirop
In the exitinstance method of CWinThread u write code to perform all deallocation.
In the exitinstance deallocatee all used memory this should help u,
CWinThread::ExitInstance()
{
AfxEndThread(0);
return 0;
}
Try this and tell me if it had yielded anything better
Regards
Mahesh Sundararaman
In the exitinstance method of CWinThread u write code to perform all deallocation.
In the exitinstance deallocatee all used memory this should help u,
CWinThread::ExitInstance()
{
AfxEndThread(0);
return 0;
}
Try this and tell me if it had yielded anything better
Regards
Mahesh Sundararaman
ASKER
jkr and Mahesh,
Thank you for your responses.
jkr - I tried your suggestion of adding a call to AfxEndThread() in the body of the thread procedure, and it made no difference: the same amount of heap was eaten. (Stepping through the code in THRDCORE.CPP, I can see that AfxEndThread() does get called as a result of the thread procedure terminating, without my calling it explicitly.)
Mahesh - the thread I'm starting is a worker thread, so has no message queue. My understanding is that CWinThread::InitInstance()
Regards,
Nick Willis
PS Here is the code fragment from THRDCORE.CPP:
UINT APIENTRY _AfxThreadEntry(void* pParam)
{
Thread started here
.
.
.
// else -- check for thread with message loop
else if (!pThread->InitInstance())
{
ASSERT_VALID(pThread);
nResult = pThread->ExitInstance();
}
.
.
.
// cleanup and shutdown the thread
threadWnd.Detach();
AfxEndThread(nResult);
return 0; // not reached
}
Put that code in a function and put a breakpoint after the function .. wait the 8.3333 minutes it takes to run.
Switch to another app and switch back.
Still see the leak? It may be just a garbage collection timing issue.
My 3c (I'll need change on that)
ASKER
Hi William,
I tried this; the heap was initially 248k, had grown to 408k just before the loop ended, then dropped back to 384k.
Some more background:
My test program's CApp::InitInstance() method starts a 'control thread'. This control thread is the thread that runs the ThreadLBProc thread 1000 times.
If I just let the program run without the breakpoint (it starts a CMainWindow in CApp::InitInstance() so the program doesn't terminate until I kill the window) then I get the same result.
Regards,
Nick
Hi Nick
How abt using the ExitThread function to see exiting the thread forcefully does not consume memory.i mean no part of memory is used even at the end of thread.
For getting the code of the currently running thread there is an API function called GetExitCodeThread which will return the code for the thread theat needs to be terminated.
Then call the global function
VOID ExitThread(
DWORD dwExitCode // exit code for this thread
);
here dwExitCode=GetExitCodeThre ad, which will return the code of thread to be terminated.This ensures that the thread is terminated.Now check if there is any memory leakage
Regards
Mahesh Sundararaman
How abt using the ExitThread function to see exiting the thread forcefully does not consume memory.i mean no part of memory is used even at the end of thread.
For getting the code of the currently running thread there is an API function called GetExitCodeThread which will return the code for the thread theat needs to be terminated.
Then call the global function
VOID ExitThread(
DWORD dwExitCode // exit code for this thread
);
here dwExitCode=GetExitCodeThre
Regards
Mahesh Sundararaman
MaheshSundararaman, maybe you should consider to post comments...
Sorry jkr i misclicked it
Regards
Mahesh Sundararaman
Regards
Mahesh Sundararaman
ASKER
Mahesh, thanks for your suggestion, but I feel that a normal thread termination should clean up its memory tidily (and I have stepped through the code in THRDCORE.CPP which appears to do just that) so I don't think that forcing a thread termination would help.
I'm basing my opinion that there *is* a leak, on the 'Heap usage' field in the process viewer utility, by clicking repeatedly on the 'Refresh' button and seeing the value rise periodically. Am I just misinterpreting the symptoms?
How about using memory diagnostics?
Dear hirop
From the website www.numega.com download the evaluation copy of BoundsChecker.It will analyse ur source code and exactly specifies where does memory leak occur.
Regards
Mahesh Sundararaman
From the website www.numega.com download the evaluation copy of BoundsChecker.It will analyse ur source code and exactly specifies where does memory leak occur.
Regards
Mahesh Sundararaman
This question didn't show any activity for more than 21 days. I will ask Community Support to close it unless you finalize it yourself within 7 days.
You can always request to keep this question open. But remember, experts can only help if you provide feedback to their comments.
Unless there is objection or further activity, I will suggest to
"refund the points and PAQ at zero points"
PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!
========
Werner
You can always request to keep this question open. But remember, experts can only help if you provide feedback to their comments.
Unless there is objection or further activity, I will suggest to
"refund the points and PAQ at zero points"
PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!
========
Werner
No comment has been added lately, so it's time to clean up this TA.
I will leave a recommendation in the Cleanup topic area that this question is:
PAQ'd with the points forfeited
Please leave any comments here within the next seven days.
PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!
martynjpearson
EE Cleanup Volunteer
I will leave a recommendation in the Cleanup topic area that this question is:
PAQ'd with the points forfeited
Please leave any comments here within the next seven days.
PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!
martynjpearson
EE Cleanup Volunteer
Yeah keep this one, some good diag techniques for threads and memory are talked about.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
UINT ThreadLBProc(LPVOID pParam)
{
AfxEndThread ( 0);
return 0;
}