John Schroedl
2009-06-01 15:34:02 UTC
Hi all,
I have a MFC-based application which is behaving very slowly when closing
certain windows which manage a large amount of data.
We've recreated the problem in a simple dialog-based test application.
Create one of those and add a Button click handler and the following:
class MyClass
{
public:
MyClass() { myData = new char[20]; }
~MyClass() {delete [] myData;}
private:
char * myData;
};
void CSlowMemoryFreeDlg::OnBnClickedOk2()
{
int start = GetTickCount();
MyClass * myArray = new MyClass[200000];
int allocTime = GetTickCount();
delete [] myArray;
int deleteTime = GetTickCount();
wchar_t msg[128];
_snwprintf_s(msg, 128, L"%d to allocate, %d to delete", allocTime - start,
deleteTime - allocTime);
OutputDebugString(msg);
}
----
Timing Output - Release build run under the debugger:
281 to allocate, 25070 to delete
----
Timing Output - Release build run outside the debugge:
(output captured with Sysinternals DebugView):
[4880] 32 to allocate, 0 to delete
----
Notice that the delete is MANY times slower when running under the debugger.
This is Release build (with pdb generation); the same exact .exe. I have not
changed any build settings. It's also fast if I run then Attach the debugger
but we don't want to have to do that every time.
My profiling shows that the time is spent overwriting the freed memory with
a sentinal value. How/Why does this automatically occur when running under a
debugger (vs. running outside the debugger)?
What visual studio/debugger/crt?? setting can I use to get the fast behavior
whether under the debugger or not?
---
I tried the following which does speed up the delete[] but I'm not sure if
the memory is really freed and what other side-effects may result. This does
not seem like a good solution especially in our Release build. We mainly want
to be able to debug the release build in a reasonable amount of time (it can
take minutes to close these windows)
// Get the current debug flags
int tmp = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
// FAST FREE
_CrtSetDbgFlag(tmp|_CRTDBG_DELAY_FREE_MEM_DF);
delete [] myArray;
// Reset flag
_CrtSetDbgFlag(tmp);
Any guidance is greatly appreciated.
John
I have a MFC-based application which is behaving very slowly when closing
certain windows which manage a large amount of data.
We've recreated the problem in a simple dialog-based test application.
Create one of those and add a Button click handler and the following:
class MyClass
{
public:
MyClass() { myData = new char[20]; }
~MyClass() {delete [] myData;}
private:
char * myData;
};
void CSlowMemoryFreeDlg::OnBnClickedOk2()
{
int start = GetTickCount();
MyClass * myArray = new MyClass[200000];
int allocTime = GetTickCount();
delete [] myArray;
int deleteTime = GetTickCount();
wchar_t msg[128];
_snwprintf_s(msg, 128, L"%d to allocate, %d to delete", allocTime - start,
deleteTime - allocTime);
OutputDebugString(msg);
}
----
Timing Output - Release build run under the debugger:
281 to allocate, 25070 to delete
----
Timing Output - Release build run outside the debugge:
(output captured with Sysinternals DebugView):
[4880] 32 to allocate, 0 to delete
----
Notice that the delete is MANY times slower when running under the debugger.
This is Release build (with pdb generation); the same exact .exe. I have not
changed any build settings. It's also fast if I run then Attach the debugger
but we don't want to have to do that every time.
My profiling shows that the time is spent overwriting the freed memory with
a sentinal value. How/Why does this automatically occur when running under a
debugger (vs. running outside the debugger)?
What visual studio/debugger/crt?? setting can I use to get the fast behavior
whether under the debugger or not?
---
I tried the following which does speed up the delete[] but I'm not sure if
the memory is really freed and what other side-effects may result. This does
not seem like a good solution especially in our Release build. We mainly want
to be able to debug the release build in a reasonable amount of time (it can
take minutes to close these windows)
// Get the current debug flags
int tmp = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
// FAST FREE
_CrtSetDbgFlag(tmp|_CRTDBG_DELAY_FREE_MEM_DF);
delete [] myArray;
// Reset flag
_CrtSetDbgFlag(tmp);
Any guidance is greatly appreciated.
John