Link to home
Start Free TrialLog in
Avatar of hirop
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(ThreadLBProc, 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!

Avatar of jkr
jkr
Flag of Germany image

The docs are pretty unprecise on that. Do you notice the same behaviour when using

UINT ThreadLBProc(LPVOID pParam)
{
 AfxEndThread ( 0);

 return 0;
}
Avatar of yashik
yashik

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
Avatar of hirop

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() and CWinThread::ExitInstance() are only called when the thread is of the UI variety. When stepping through the code, the call to CWinThread::ExitInstance()is not made.

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)

 
Avatar of hirop

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=GetExitCodeThread, 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
MaheshSundararaman, maybe you should consider to post comments...
Sorry jkr i misclicked it

Regards
Mahesh Sundararaman
Avatar of hirop

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
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
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
Yeah keep this one, some good diag techniques for threads and memory are  talked about.
ASKER CERTIFIED SOLUTION
Avatar of YensidMod
YensidMod

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial