Thread View: borland.public.cppbuilder.nativeapi
14 messages
14 total messages
Started by Dan Mayo
Thu, 18 Jan 2007 19:41
Creating new TForm causes 'Out of Resources' error on WinXP
Author: Dan Mayo
Date: Thu, 18 Jan 2007 19:41
Date: Thu, 18 Jan 2007 19:41
20 lines
1553 bytes
1553 bytes
Hi, I have a fairly simple form that I dynamically create throughout a program I am working on. However, every once in awhile the program crashes due to a 'Out of Resources' error (according to Windows) however, when I log the amount of memory in use and available; there is plenty of physical memory yet. Using a tool to help discover where the code was dying, I found out it was on the 'new' call when I dynamically create the new form. Shortly after creating the form and temporarily displaying some things I always close the form and then call the delete operator. Why am I getting the "Out of Resources" error? The form only contains a TButton, a TCaption, and a TProgressBar. Ideas? Thanks in advance! Dan
Re: Creating new TForm causes 'Out of Resources' error on WinXP
Author: Remy Lebeau (TeamB)
Date: Thu, 18 Jan 2007 20:00
Date: Thu, 18 Jan 2007 20:00
37 lines
2069 bytes
2069 bytes
"Dan Mayo" <dmayo@dickey-john.com> wrote in message news:45afcda9$1@newsgroups.borland.com... > I have a fairly simple form that I dynamically create throughout a > program I am working on. However, every once in awhile the > program crashes due to a 'Out of Resources' error (according to > Windows) GDI resources are very limited. > however, when I log the amount of memory in use and available; > there is plenty of physical memory yet. Available physical memory is different then available GDI resources. > Using a tool to help discover where the code was dying, I found out > it was on the 'new' call when I dynamically create the new form. Shortly > after creating the form and temporarily displaying some things I always > close the form and then call the delete operator. Are you absolutely sure that 'delete' is always being called? In any case, how much UI resources are you already using before creating the new form instance? > Why am I getting the "Out of Resources" error? Because you are running low on available resources ;-) > The form only contains a TButton, a TCaption, and a TProgressBar. But what does the rest of your UI contain? Gambit
Re: Creating new TForm causes 'Out of Resources' error on WinXP
Author: Dan Mayo
Date: Thu, 18 Jan 2007 20:23
Date: Thu, 18 Jan 2007 20:23
64 lines
3264 bytes
3264 bytes
> GDI resources are very limited.
Ok; I'll google this one to get a better idea...
> Available physical memory is different then available GDI resources.
Perhaps google will be my friend here too. :)
> Are you absolutely sure that 'delete' is always being called? In any
> case, how much UI resources are you already using before creating the
> new form instance?
YES There is no other way for the code to exit from that function.
> But what does the rest of your UI contain?
My whole user interface has a number of other buttons, labels, graphs,
etc. The weird thing I don't understand is that I am basically in a loop:
Simplified code is as follows:
void MyClass::TheLoop()
{
bool Stop = false;
while (!Stop)
{
TCustomForm *theDialogThatCrashes;
theDialogThatCrashes = new TCustomForm(this); //<-- This is where
the out of resources occurs
theDialogThatCrashes->Visible = true;
TriggerLongHardwareRelatedTask();
bool DoingSomeLongHardwareRelatedTask = true;
while (DoingSomeLongHardwareRelatedTask)
{
//update the progress bar
if (theDialogThatCrashes->ProgressBar->Position >
theDialogThatCrashes->ProgressBar->Max)
{
theDialogThatCrashes->ProgressBar->Position = 0;
}
else
{
theDialogThatCrashes->ProgressBar->Position += 1;
}
DoingSomeLongHardwareRelatedTask = !HardwareTaskComplete();
Application->ProcessMessages(); //call this so that Button
event on theDialogThatCrashes is called; the button event sets that
forms Stopped boolean value to true if it is pressed
if (theDialogThatCrashes->Stopped)
{
DoingSomeLongHardwareRelatedTask = false;
Stop = true;
}
}
theDialogThatCrashes->Visible = false;
delete theDialogThatCrashes;
}
}
For simplicity, the hardware event is sending a message out of the
serial port and waiting for the RXBuffer on taht serial port to reach a
certain byte level.
I don't see why I'm running out of resources with the above code.
Any suggestions?
Re: Creating new TForm causes 'Out of Resources' error on WinXP
Author: Remy Lebeau (TeamB)
Date: Thu, 18 Jan 2007 21:41
Date: Thu, 18 Jan 2007 21:41
70 lines
3199 bytes
3199 bytes
"Dan Mayo" <dmayo@dickey-john.com> wrote in message
news:45afd751$1@newsgroups.borland.com...
> YES There is no other way for the code to exit from that function.
What about if exceptions occur? You are not protecting your code from
that scenerio at all.
> My whole user interface has a number of other buttons, labels,
graphs,
> etc. The weird thing I don't understand is that I am basically in a
loop:
You don't need to re-create the form on each iteration of the loop.
You could create it once and then let the loop show/hide it as needed.
Try this instead:
void MyClass::TheLoop()
{
TMyForm *theDialog = new TMyForm(NULL); // no Owner needed
try
{
bool Stop = false;
while( !Stop )
{
theDialog->ProgressBar->Position = 0;
theDialog->ProgressBar->Max = ...;
theDialog->Stopped = false;
theDialog->Show();
TriggerLongHardwareRelatedTask();
bool DoingSomeLongHardwareRelatedTask = true;
while( DoingSomeLongHardwareRelatedTask && !Stop )
{
if( theDialog->ProgressBar->Position <
theDialog->ProgressBar->Max )
theDialog->ProgressBar->StepIt(); // Set the
Step property to 1
else
theDialog->ProgressBar->Position = 0;
DoingSomeLongHardwareRelatedTask =
!HardwareTaskComplete();
Application->ProcessMessages();
Stop = theDialog->Stopped;
}
theDialog->Hide();
}
}
__finally
{
delete theDialogThatCrashes;
}
}
Now, with that said, you should seriously consider moving the hardware
code into a separate worker thread instead. The thread can post
notifications about its status to the main thread to update the
dialog. It is not good to perform lengthy operations in the main
thead, and call ProcessMessages() like that can introduce other subtle
problems elsewhere.
Gambit
Re: Creating new TForm causes 'Out of Resources' error on WinXP
Author: Dan Mayo
Date: Thu, 18 Jan 2007 22:13
Date: Thu, 18 Jan 2007 22:13
89 lines
4261 bytes
4261 bytes
Well, I did say it was a simplified version :)
I should have done a better job of writing the demo code. The actual
code is within a function that reads from the hardware and shows a
progress bar basically indicating the timeout period. The program
crashes at random times of program execution after a random number of
calls to this function.
I hear your point about threads. I suppose I can look at that.
But back to the original point, I don't know why the error is occurring;
I don't believe there are any other exit points or any exceptions thrown
except out or system resources. I am using Eureka Log to track program
execution and that's how I identified this spot; it doesn't show any
other exceptions and PC-Lint doesn't report any errors in the code at all.
Remy Lebeau (TeamB) wrote:
> "Dan Mayo" <dmayo@dickey-john.com> wrote in message
> news:45afd751$1@newsgroups.borland.com...
>
>> YES There is no other way for the code to exit from that function.
>
> What about if exceptions occur? You are not protecting your code from
> that scenerio at all.
>
>> My whole user interface has a number of other buttons, labels,
> graphs,
>> etc. The weird thing I don't understand is that I am basically in a
> loop:
>
> You don't need to re-create the form on each iteration of the loop.
> You could create it once and then let the loop show/hide it as needed.
>
> Try this instead:
>
> void MyClass::TheLoop()
> {
> TMyForm *theDialog = new TMyForm(NULL); // no Owner needed
> try
> {
> bool Stop = false;
> while( !Stop )
> {
> theDialog->ProgressBar->Position = 0;
> theDialog->ProgressBar->Max = ...;
> theDialog->Stopped = false;
> theDialog->Show();
>
> TriggerLongHardwareRelatedTask();
>
> bool DoingSomeLongHardwareRelatedTask = true;
> while( DoingSomeLongHardwareRelatedTask && !Stop )
> {
> if( theDialog->ProgressBar->Position <
> theDialog->ProgressBar->Max )
> theDialog->ProgressBar->StepIt(); // Set the
> Step property to 1
> else
> theDialog->ProgressBar->Position = 0;
>
> DoingSomeLongHardwareRelatedTask =
> !HardwareTaskComplete();
>
> Application->ProcessMessages();
> Stop = theDialog->Stopped;
> }
>
> theDialog->Hide();
> }
> }
> __finally
> {
> delete theDialogThatCrashes;
> }
> }
>
>
> Now, with that said, you should seriously consider moving the hardware
> code into a separate worker thread instead. The thread can post
> notifications about its status to the main thread to update the
> dialog. It is not good to perform lengthy operations in the main
> thead, and call ProcessMessages() like that can introduce other subtle
> problems elsewhere.
>
>
> Gambit
>
>
Re: Creating new TForm causes 'Out of Resources' error on WinXP
Author: David Pratt
Date: Fri, 19 Jan 2007 11:27
Date: Fri, 19 Jan 2007 11:27
12 lines
1439 bytes
1439 bytes
> void MyClass::TheLoop()
> {
> bool Stop = false;
> while (!Stop)
> {
> TCustomForm *theDialogThatCrashes;
> theDialogThatCrashes = new TCustomForm(this); //<-- This is where
> the out of resources occurs
I don't know about subsequent versions, but Version 5 says do NOT create
instances of TCustom form; Instantiate descendants of TCustomForm instead.
Re: Creating new TForm causes 'Out of Resources' error on WinXP
Author: Bob Gonder
Date: Fri, 19 Jan 2007 13:25
Date: Fri, 19 Jan 2007 13:25
7 lines
1507 bytes
1507 bytes
Dan Mayo wrote: >But back to the original point, I don't know why the error is occurring; Also note that there are other resources than GDI, such as various handles. If you don't always close your handles, they can leak and run you out of resources.
Re: Creating new TForm causes 'Out of Resources' error on WinXP
Author: Dan Mayo
Date: Fri, 19 Jan 2007 14:19
Date: Fri, 19 Jan 2007 14:19
21 lines
1961 bytes
1961 bytes
Bob Gonder wrote: > Dan Mayo wrote: > >> But back to the original point, I don't know why the error is occurring; > > Also note that there are other resources than GDI, such as various > handles. If you don't always close your handles, they can leak and run > you out of resources. > > How can I track this bug down? I am running the application with Task Manager open and I'm watching memory usage and #GDI Object. My memory usage hovers around 12MB and the number of GDIs hovers around 180. I can see the memory usage and GDI count go up as the program uses more and then right back down as objects are freed. The memory doesn't climb out of control; nor does the GDI count. Any ideas?
Re: Creating new TForm causes 'Out of Resources' error on WinXP
Author: Dan Mayo
Date: Fri, 19 Jan 2007 14:32
Date: Fri, 19 Jan 2007 14:32
20 lines
2077 bytes
2077 bytes
From the help file: "Note: When working with form objects, do not explicitly call the Free or Destroy method to free them. Instead, use the Release method, which waits until all event handlers have finished executing." Does this mean I should call "theDialog->Release();" rather than "delete theDialog;"? Reading the "Release()" function call help the note appears contradictory to the TForm() section: "Note: Release returns immediately to the caller. It does not wait for the form to be freed before returning." So does Release() wait for everything to be done first before returning to the next line in code? Do I need to call both Release() and then delete? Is there something I should do to make sure that Release() has finished prior to calling delete? Dan
Re: Creating new TForm causes 'Out of Resources' error on WinXP
Author: Dan Mayo
Date: Fri, 19 Jan 2007 15:11
Date: Fri, 19 Jan 2007 15:11
29 lines
2294 bytes
2294 bytes
Is there anything wrong with doing destruction of a form like this? theForm->Release(); Application->ProcessMessages(); //then go on my merry way... (I was noticing without ProcessMessages that theForm was still in memory.. Is there a better way? Dan Mayo wrote: > From the help file: > "Note: When working with form objects, do not explicitly call the > Free or Destroy method to free them. Instead, use the Release method, > which waits until all event handlers have finished executing." > > Does this mean I should call "theDialog->Release();" rather than "delete > theDialog;"? > > Reading the "Release()" function call help the note appears > contradictory to the TForm() section: > > "Note: Release returns immediately to the caller. It does not wait > for the form to be freed before returning." > > So does Release() wait for everything to be done first before returning > to the next line in code? Do I need to call both Release() and then > delete? Is there something I should do to make sure that Release() has > finished prior to calling delete? > > Dan
Re: Creating new TForm causes 'Out of Resources' error on WinXP
Author: Remy Lebeau (TeamB)
Date: Fri, 19 Jan 2007 19:00
Date: Fri, 19 Jan 2007 19:00
48 lines
2861 bytes
2861 bytes
"Dan Mayo" <dmayo@dickey-john.com> wrote in message
news:45b0d69a$1@newsgroups.borland.com...
> "Note: When working with form objects, do not explicitly call the
Free
> or Destroy method to free them. Instead, use the Release method,
which
> waits until all event handlers have finished executing."
Do not call Free() or Destroy() ('delete' in C++) while inside one of
the TForm's own event handlers. That is the only place where you need
to use Release() if the form wants to free itself. Otherwise, Free()
and Destroy() ('delete') work fine.
> Does this mean I should call "theDialog->Release();" rather than
> "delete theDialog;"?
There is nothing wrong with doing that in the code you showed. Using
'delete' is the proper thing to do in that situation.
> Reading the "Release()" function call help the note appears
> contradictory to the TForm() section:
>
> "Note: Release returns immediately to the caller. It does not wait
> for the form to be freed before returning."
That is correct. Release() posts a CM_RELEASE message to the message
queue. The form is freed when the message is processed later on.
That allows any active and pending event handlers to finish running
before the form is freed.
> So does Release() wait for everything to be done first before
> returning to the next line in code?
No.
> Do I need to call both Release() and then delete?
No. That will crash your code as the TForm will be freed twice.
> Is there something I should do to make sure that Release() has
> finished prior to calling delete?
Stop using Release() in this situation. It does not apply at all.
Gambit
Re: Creating new TForm causes 'Out of Resources' error on WinXP
Author: Remy Lebeau (TeamB)
Date: Fri, 19 Jan 2007 19:02
Date: Fri, 19 Jan 2007 19:02
24 lines
1856 bytes
1856 bytes
"Dan Mayo" <dmayo@dickey-john.com> wrote in message news:45b0dfca@newsgroups.borland.com... > Is there anything wrong with doing destruction of a form like this? > theForm->Release(); > Application->ProcessMessages(); Technically no, but it is not the right way to free the form in this situation. > I was noticing without ProcessMessages that theForm was still in memory.. That is because the message posted by Release() is not processed, so the form is not freed. > Is there a better way? You already know a better way - use 'delete' instead. There is nothing in your code that warrants the use of Release(). Gambit
Re: Creating new TForm causes 'Out of Resources' error on WinXP
Author: Bruce Salzman
Date: Fri, 19 Jan 2007 19:21
Date: Fri, 19 Jan 2007 19:21
16 lines
1430 bytes
1430 bytes
"Dan Mayo" <dmayo@dickey-john.com> wrote in message news:45afd751$1@newsgroups.borland.com... > > For simplicity, the hardware event is sending a message out of the > serial port and waiting for the RXBuffer on taht serial port to > reach a certain byte level. > > I don't see why I'm running out of resources with the above code. > Is it possible that 'theDialogThatCrashes' is consuming resources and not cleaning up after itself? -- Bruce
Re: Creating new TForm causes 'Out of Resources' error on WinXP
Author: Dan Mayo
Date: Fri, 19 Jan 2007 20:28
Date: Fri, 19 Jan 2007 20:28
36 lines
2845 bytes
2845 bytes
Remy Lebeau (TeamB) wrote: >> Is there a better way? > > You already know a better way - use 'delete' instead. There is > nothing in your code that warrants the use of Release(). I do appreciate the help and the comments. I was under the impression that the Release(); ProcessMessages() call actually fixed the problem as my code ran much much longer than it ever had before in this loop. However, it does still occur. With the straight 'delete' operator, my code lasts approximately 230 cycles; with the Release(); ProcessMessages() operators instead of delete, the code goes nearly 800 cycles. During each of these cycles are several hardware read/write commands, each dynamically creating and destroying that form; and with each cycle nearly 24k of memory is saved. The data is stored in a TStringGrid. Perhaps that is the real problem. I don't quite see why since I can easily open a file and fill in a TStringGrid with 2x the amount of data collected during this loop and then dynamically create the dialog in question though. But I've been wrong before :) As I said before the form in question is rather simple, and it has a TProgressBar, TLabel, and TButton on it; that's it. I'm confused (1) why this is still happening, although basically Remy says I haven't done anything to fix the problem, which I can buy; however that brings me to my second confusion (2) why my code consistently runs much longer with the Release() than it did with just the delete. Dan
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads