Low Memory situations | developer.brewmp.com Low Memory situations | developer.brewmp.com

Developer

Low Memory situations

The docs say that the app is expected to handle low memory conditions 'gracefully'. At several points in my application, user messages will appear that require small allocations to load and display strings from the resource file.

Am I expected to have a 'low memory' string cached?

Right now, the app will not crash, but messages will also
not appear.

In windows, for example, Messagebox is always cached in the
system so that one can safely display "Low memory" in
a messagebox.

Is there a similar resource in Brew?

In certain cases, if I enter my app with insufficient memory, it
will simply not load and release what it has allocated.

Is this sufficient to pass, or is an error message expected?

Perhaps you could also tell us how low to set the
memory in the shaker to duplicate what TBT tests with.

thanks!!

OK, since I am not getting any response here, I will simply
force an exit of my application if any Mallocs fail.

OK, since I am not getting any response here, I will simply
force an exit of my application if any Mallocs fail.

My assumption would be that the concern would be the app not crashing. But, you know how assumptions go.
Look on the bright side, you finally got a response. Useless or not :)

My assumption would be that the concern would be the app not crashing. But, you know how assumptions go.
Look on the bright side, you finally got a response. Useless or not :)

ok, im at this stage in my code now too. In low memory situations my application will not crash, worst case sernario is an image isnt displayed or the program exits with no warning.
as for jmillers post, it remided my of something my C teacher once told me. Allocate a chunk memory at the start of your application. The first time you encounter a bad malloc, free the global pointer of that chunk of memory you've been holding on too. Then use it to display somethings and exit your program cleanly.
This is a horrible solution to a crappy problem. I wish, like you, that i had a message box like object. The best thing about messagebox in win32 is that you don't need to enter any parameters. MessageBox(0,0,0,0); will pop up a message box. If i had something like a message box i could add it to my 'new' overloaded function.
inline void* operator new( size_t sz )
{
DBGPRINTF( "new" );
void *tmp = MALLOC(sz);
if( !tmp )
{
MessageBox(0,0,"ERROR", "Cannot Allocate Memmory");
exit(0);
}
return tmp;
;
is something like this possible in BREW, or am i going to have to pass my application struct into new() everytime so i can display an error message?

ok, im at this stage in my code now too. In low memory situations my application will not crash, worst case sernario is an image isnt displayed or the program exits with no warning.
as for jmillers post, it remided my of something my C teacher once told me. Allocate a chunk memory at the start of your application. The first time you encounter a bad malloc, free the global pointer of that chunk of memory you've been holding on too. Then use it to display somethings and exit your program cleanly.
This is a horrible solution to a crappy problem. I wish, like you, that i had a message box like object. The best thing about messagebox in win32 is that you don't need to enter any parameters. MessageBox(0,0,0,0); will pop up a message box. If i had something like a message box i could add it to my 'new' overloaded function.
inline void* operator new( size_t sz )
{
DBGPRINTF( "new" );
void *tmp = MALLOC(sz);
if( !tmp )
{
MessageBox(0,0,"ERROR", "Cannot Allocate Memmory");
exit(0);
}
return tmp;
;
is something like this possible in BREW, or am i going to have to pass my application struct into new() everytime so i can display an error message?

j0rd:
I guess you would like the MessageBox be popped up rightaway, before this overloaded new operator returns. But it will conflict with BREW's async mode.
If the MessageBox is implemented by IMenu** stuff, then after a IDisplayUpdate(), you need to return to BREW to make the actual drawing happening. Yet before that happens, the caller of this new operator still need to check the return the pointer is null or not.
Regards.
c@ini@o

j0rd:
I guess you would like the MessageBox be popped up rightaway, before this overloaded new operator returns. But it will conflict with BREW's async mode.
If the MessageBox is implemented by IMenu** stuff, then after a IDisplayUpdate(), you need to return to BREW to make the actual drawing happening. Yet before that happens, the caller of this new operator still need to check the return the pointer is null or not.
Regards.
c@ini@o

to what extent to i have to test this? Should my program display and error message and exit everytime a HEAP Alloc fails? I'm curious because i don't want to fail TBT for not exiting my program even if the alloc isn't crucial. I guess the same applies for stuff like ISHELL_LoadImage(), if i get a NULL pointer from this i should be displaying an error and exiting my program.

to what extent to i have to test this? Should my program display and error message and exit everytime a HEAP Alloc fails? I'm curious because i don't want to fail TBT for not exiting my program even if the alloc isn't crucial. I guess the same applies for stuff like ISHELL_LoadImage(), if i get a NULL pointer from this i should be displaying an error and exiting my program.

Yep, you have to do that. During testing, they will try the application with low memory available, and with deleting files..
/kUfa

Yep, you have to do that. During testing, they will try the application with low memory available, and with deleting files..
/kUfa

they will delete files after i create them? in the applications directory? Hm...ill have to try that.

they will delete files after i create them? in the applications directory? Hm...ill have to try that.

I too am confused about what exactly must be done to "gracefully handle" low memory situations. I'll be very specific in my questions, hopefully someone out there will be very specific with the answers.
1. In low memory situations, suppose my code has a MALLOC that fails. The simplest solution is for me to force an exit whenever this occurs. Will this satisfy TB testing?
2. If this does NOT satisfy TB testing, then must I show an error message prior to exiting the app? Must it be shown for some minimu amount of time?
3. What is the standard procedure for handling out-of-memory errors? I have seen suggestions like using SendEvent to send a user event to your own app, and in the event handler you show an error screen. To do this you will need to have the user screen already created (you are out of memory so you cannot create it on the fly). If one does this, then what is the standard procedure for exiting the app? Is it OK to exit upon the very next keypress (any key) when the error screen is displayed?
4. What I would really really prefer to do is to just exit the app immediately when a MALLOC fails. I know I am repeating myself here but I can't see a specific answer to this in the forums. If I do this, will it pass TB testing?
Thanks

I too am confused about what exactly must be done to "gracefully handle" low memory situations. I'll be very specific in my questions, hopefully someone out there will be very specific with the answers.
1. In low memory situations, suppose my code has a MALLOC that fails. The simplest solution is for me to force an exit whenever this occurs. Will this satisfy TB testing?
2. If this does NOT satisfy TB testing, then must I show an error message prior to exiting the app? Must it be shown for some minimu amount of time?
3. What is the standard procedure for handling out-of-memory errors? I have seen suggestions like using SendEvent to send a user event to your own app, and in the event handler you show an error screen. To do this you will need to have the user screen already created (you are out of memory so you cannot create it on the fly). If one does this, then what is the standard procedure for exiting the app? Is it OK to exit upon the very next keypress (any key) when the error screen is displayed?
4. What I would really really prefer to do is to just exit the app immediately when a MALLOC fails. I know I am repeating myself here but I can't see a specific answer to this in the forums. If I do this, will it pass TB testing?
Thanks

I just display a simple string and then quickly exit. It passed TBT.
I use the same method if for some reason a resource load fails.
It's not pretty, but it's not a pretty situation....

I just display a simple string and then quickly exit. It passed TBT.
I use the same method if for some reason a resource load fails.
It's not pretty, but it's not a pretty situation....

i just make a global function that i call if i get any big fatal errors. The function prompts a MessageBox then quits after 2 seconds.
The user should never see this error box, but it's there just in case something horible happends.

i just make a global function that i call if i get any big fatal errors. The function prompts a MessageBox then quits after 2 seconds.
The user should never see this error box, but it's there just in case something horible happends.

What if sometimes I don't need to exit? I have allocated some chunks at launch (begining of an app). Later on, at some spots, I do need extra heap memory, but if it's not there, I can simply do something else (and I am doing something else, there is no error message or exit of an app in that case)... Could that be a problem with TBT or not? I don't see why would that be a problem, but just in case.

What if sometimes I don't need to exit? I have allocated some chunks at launch (begining of an app). Later on, at some spots, I do need extra heap memory, but if it's not there, I can simply do something else (and I am doing something else, there is no error message or exit of an app in that case)... Could that be a problem with TBT or not? I don't see why would that be a problem, but just in case.

There's nothing that says your app. has to exit if a MALLOC failure occurs. If you can do something else in order to handle the failure gracefully, that's definitely preferable to exiting. The only thing that TBT cares about is that your app. recognizes and deals with the alloc failure. The definition of "deals with" is left to the developer.
HTH,
MB

There's nothing that says your app. has to exit if a MALLOC failure occurs. If you can do something else in order to handle the failure gracefully, that's definitely preferable to exiting. The only thing that TBT cares about is that your app. recognizes and deals with the alloc failure. The definition of "deals with" is left to the developer.
HTH,
MB

This is a really tricky problem.
Does everyone realize that for each function called that may fail, the caller has to check to see if a fatal event has occurred and then exit and that has to be done for the entire call chain until the handleEvent has been exited?
Even if one was to use CloseApplet() in a New or Malloc. CloseApplet is still an async op and after CloseApplet has returned, one still has to deal with a fatal problem in the sense that nothing should be touched or done until one has exited the HandleEvent(...) function?
Now, if one does not want to exit the Applet, then one has to code alternative paths...blehh...

This is a really tricky problem.
Does everyone realize that for each function called that may fail, the caller has to check to see if a fatal event has occurred and then exit and that has to be done for the entire call chain until the handleEvent has been exited?
Even if one was to use CloseApplet() in a New or Malloc. CloseApplet is still an async op and after CloseApplet has returned, one still has to deal with a fatal problem in the sense that nothing should be touched or done until one has exited the HandleEvent(...) function?
Now, if one does not want to exit the Applet, then one has to code alternative paths...blehh...

You can use exit(0) with Brew? What are the events that will be sent to the app? Your message box is also async, so I doubt the user will see that message because you exited right away...
===
inline void* operator new( size_t sz )
{
DBGPRINTF( "new" );
void *tmp = MALLOC(sz);
if( !tmp )
{
MessageBox(0,0,"ERROR", "Cannot Allocate Memmory");
exit(0);
}
return tmp;
;

You can use exit(0) with Brew? What are the events that will be sent to the app? Your message box is also async, so I doubt the user will see that message because you exited right away...
===
inline void* operator new( size_t sz )
{
DBGPRINTF( "new" );
void *tmp = MALLOC(sz);
if( !tmp )
{
MessageBox(0,0,"ERROR", "Cannot Allocate Memmory");
exit(0);
}
return tmp;
;

Yeah, but i check for errors on my win32 programs, unix ones, brew ones, etc...
We are not here to corrupt the user's phone, and with a clean way of programming, it's not that hard to implement..
/kUfa

Yeah, but i check for errors on my win32 programs, unix ones, brew ones, etc...
We are not here to corrupt the user's phone, and with a clean way of programming, it's not that hard to implement..
/kUfa

Nope doesnt work..
/kUfa

Nope doesnt work..
/kUfa

It's not hard, but tedious without exceptions.

It's not hard, but tedious without exceptions.

Well, depends on how you usually code. Personnaly i decided not to use exceptions since the overheads are quite big..
/kUfa

Well, depends on how you usually code. Personnaly i decided not to use exceptions since the overheads are quite big..
/kUfa

Are you saying exceptions are available with Brew/C++ ?
When you talk about overhead, are you talking about time or space or both?
How much space are we talking about per function in the call chain?
I mean, I would not mind 10-30k total run-time overhead to keep the code simple.
Memories are not THAT hard to come by in Brew devices.

Are you saying exceptions are available with Brew/C++ ?
When you talk about overhead, are you talking about time or space or both?
How much space are we talking about per function in the call chain?
I mean, I would not mind 10-30k total run-time overhead to keep the code simple.
Memories are not THAT hard to come by in Brew devices.

exceptions are not available in the BREW platform. Error checking is not that tedious, just wrap all your function calls ala Richard Stevens. It's not what i do in brew, but could be done to make checking for fatal errors streamline.
as for the overhead of being to high, i think he's refering to code bloat. It takes alot of extra code to check for error with exceptions if you are planning to do it right (java style).
time overhead i don't think would be an issue since exceptions should never occur in proper code, under proper conditions. But if they do it's probably something fatal which would require you to exit the program or something along those lines.

exceptions are not available in the BREW platform. Error checking is not that tedious, just wrap all your function calls ala Richard Stevens. It's not what i do in brew, but could be done to make checking for fatal errors streamline.
as for the overhead of being to high, i think he's refering to code bloat. It takes alot of extra code to check for error with exceptions if you are planning to do it right (java style).
time overhead i don't think would be an issue since exceptions should never occur in proper code, under proper conditions. But if they do it's probably something fatal which would require you to exit the program or something along those lines.

So there's no way to write a string on the screen and quit the app synchronously in Brew? You need new code to handle every possible memory allocation code path, or am I missing something here? There must be a way to simply call a function whenever there is an error and not have to bloat the code in any other way...

So there's no way to write a string on the screen and quit the app synchronously in Brew? You need new code to handle every possible memory allocation code path, or am I missing something here? There must be a way to simply call a function whenever there is an error and not have to bloat the code in any other way...

Checking when a new fails is easy enough, but what about cases when a C++ object is created on the stack, like
void f()
{
Point oldPoint = ....;
Point p = (oldPoint); // copy constructor

Anyone knows a good way to detected that creation of p has failed? Is against best practices to do a copy constructor ops?
I thought about doing a:
Point *p = new Point();
if(p == NULL)
p->clone(oldPoint);
but I am interested in what people do...
thanks...

Checking when a new fails is easy enough, but what about cases when a C++ object is created on the stack, like
void f()
{
Point oldPoint = ....;
Point p = (oldPoint); // copy constructor

Anyone knows a good way to detected that creation of p has failed? Is against best practices to do a copy constructor ops?
I thought about doing a:
Point *p = new Point();
if(p == NULL)
p->clone(oldPoint);
but I am interested in what people do...
thanks...

Checking when a new fails is easy enough, but what about cases when a C++ object is created on the stack, like
void f()
{
Point oldPoint = ....;
Point p = (oldPoint); // copy constructor

Anyone knows a good way to detected that creation of p has failed? Is against best practices to do a copy constructor ops?
I thought about doing a:
Point *p = new Point();
if(p != NULL)
p->clone(oldPoint);
but I am interested in what people do...
thanks...

Checking when a new fails is easy enough, but what about cases when a C++ object is created on the stack, like
void f()
{
Point oldPoint = ....;
Point p = (oldPoint); // copy constructor

Anyone knows a good way to detected that creation of p has failed? Is against best practices to do a copy constructor ops?
I thought about doing a:
Point *p = new Point();
if(p != NULL)
p->clone(oldPoint);
but I am interested in what people do...
thanks...

Stack space is extremely limited, and likely allocated at program initialization (I'm not sure exactly how the mod loader works but this is how I would do it).
So, if something is of any appreciable size, then it should be allocated dynamically. I wouldn't create c++ objects on the stack unless I were sure they were REAL SMALL. The safe ting to do is to allocate and check.
Just my .02.

Stack space is extremely limited, and likely allocated at program initialization (I'm not sure exactly how the mod loader works but this is how I would do it).
So, if something is of any appreciable size, then it should be allocated dynamically. I wouldn't create c++ objects on the stack unless I were sure they were REAL SMALL. The safe ting to do is to allocate and check.
Just my .02.

Even in Win32 environment I never felt comfortable working with objects on the stack. I ALWAYS create objects dynamically no matter when or where. It gives me a maximum of control and the ability to further optimize certain behaviors in my own memory manager if need be. It also virtually makes the need for exception handling redundant. Like some other C++ features I have never taking a liking to exception handling. It is convoluting your code, illogical, hard to follow and error prone, particularly once you are mixing code that uses exception handling and code that doesn't.

Even in Win32 environment I never felt comfortable working with objects on the stack. I ALWAYS create objects dynamically no matter when or where. It gives me a maximum of control and the ability to further optimize certain behaviors in my own memory manager if need be. It also virtually makes the need for exception handling redundant. Like some other C++ features I have never taking a liking to exception handling. It is convoluting your code, illogical, hard to follow and error prone, particularly once you are mixing code that uses exception handling and code that doesn't.

Quote:Originally posted by Dragon
Even in Win32 environment I never felt comfortable working with objects on the stack. I ALWAYS create objects dynamically no matter when or where. It gives me a maximum of control and the ability to further optimize certain behaviors in my own memory manager if need be. It also virtually makes the need for exception handling redundant. Like some other C++ features I have never taking a liking to exception handling. It is convoluting your code, illogical, hard to follow and error prone, particularly once you are mixing code that uses exception handling and code that doesn't.
Yeah exception handling can certainly make for sloppy code. However, it is very hard to code win32 C++ that uses COM without exception handling. Especially if you use ADO.
MS codes all of their stuff to throw exceptions, but it is
always prudent to check return codes also. Otherwise you are just using a goto (yuck!).
I must say, though, that Brew API's often do not have return codes, and one has to sometimes resort to _other_ methods to discover a problem. (Like, for instance LoadResImage not having enough memory to load an image but still returning success and a valid pointer with an empty bitmap attached to it -- hello black screen!).
I am somewhat disappointed at the handset testing that goes on. I mean how can they not have a handset testing suite that AT LEAST tests every API? I had a long discussion with someone at the lab one time about this and really did not get a good answer (I was reporting a graphics bug in Brew 2.0).

Quote:Originally posted by Dragon
Even in Win32 environment I never felt comfortable working with objects on the stack. I ALWAYS create objects dynamically no matter when or where. It gives me a maximum of control and the ability to further optimize certain behaviors in my own memory manager if need be. It also virtually makes the need for exception handling redundant. Like some other C++ features I have never taking a liking to exception handling. It is convoluting your code, illogical, hard to follow and error prone, particularly once you are mixing code that uses exception handling and code that doesn't.
Yeah exception handling can certainly make for sloppy code. However, it is very hard to code win32 C++ that uses COM without exception handling. Especially if you use ADO.
MS codes all of their stuff to throw exceptions, but it is
always prudent to check return codes also. Otherwise you are just using a goto (yuck!).
I must say, though, that Brew API's often do not have return codes, and one has to sometimes resort to _other_ methods to discover a problem. (Like, for instance LoadResImage not having enough memory to load an image but still returning success and a valid pointer with an empty bitmap attached to it -- hello black screen!).
I am somewhat disappointed at the handset testing that goes on. I mean how can they not have a handset testing suite that AT LEAST tests every API? I had a long discussion with someone at the lab one time about this and really did not get a good answer (I was reporting a graphics bug in Brew 2.0).

I have found a problem with ISHELL_CreateInstance. It crashes the phone when there is no memory available and I try to create
IAddressBook interface.
I think the only way to avoid crashing is to check if there is memory available just before calling ISHELL_CreateInstance. But this is just radiculous!
Zim

I have found a problem with ISHELL_CreateInstance. It crashes the phone when there is no memory available and I try to create
IAddressBook interface.
I think the only way to avoid crashing is to check if there is memory available just before calling ISHELL_CreateInstance. But this is just radiculous!
Zim

Quote:Originally posted by ziemowit
I have found a problem with ISHELL_CreateInstance. It crashes the phone when there is no memory available and I try to create
IAddressBook interface.
I think the only way to avoid crashing is to check if there is memory available just before calling ISHELL_CreateInstance. But this is just radiculous!
Zim
Why not just move this createinstance below some other code (like code that loads a graphic). Then the code above it will fail and exit.
BTW, on some apps, I have evaluated free memory before attempting to do anything else. It really was not a big deal.
Just be glad you found it now...

Quote:Originally posted by ziemowit
I have found a problem with ISHELL_CreateInstance. It crashes the phone when there is no memory available and I try to create
IAddressBook interface.
I think the only way to avoid crashing is to check if there is memory available just before calling ISHELL_CreateInstance. But this is just radiculous!
Zim
Why not just move this createinstance below some other code (like code that loads a graphic). Then the code above it will fail and exit.
BTW, on some apps, I have evaluated free memory before attempting to do anything else. It really was not a big deal.
Just be glad you found it now...

check next thread....:)

check next thread....:)

my app needs 200kb heap to run properly... i'm planning to give low memory message and close app, if enough memory is not avialbale...
Also what is meaning of EFS restriction on max space, in MIF...
will this pass TBT ?
sdg

my app needs 200kb heap to run properly... i'm planning to give low memory message and close app, if enough memory is not avialbale...
Also what is meaning of EFS restriction on max space, in MIF...
will this pass TBT ?
sdg