Topic: What to do when the memory runs out, Was: can't use STL in commercial applications


Author: kanze@gabi-soft.fr (J. Kanze)
Date: 1996/10/14
Raw View
Joe Porkka <joe@fantasia.avid.com> writes:

    [Since this thread is no longer really appropriate to comp.std.c++,
I've cross-posted to comp.lang.c++.moderated, and set followups there.]

> The short form of this post:
>  Many (if not most) programs do not deal well with out of memory.
>  For no applications is this acceptable. (IMHO)

Agreed.  I think most of our differences can be characterized by a
difference of opinion as to what is typical.

>  This does not mean that its OK for the C++ standard to endorse
>  this behavior, and in fact make it impossible to create well
>  behaved applications.

Heartily agreed.  The C++ standard must allow good programming, even if
it cannot impose it.

>  For some applications, printing "out of memory" and exiting, is
>  an entirely appropriate way to deal with the problem.
>  For other applications, it is not acceptable to exit.

> Arguments follow:
>
>
>  [James Kanze]
>  >  What would you suggest that a compiler do in an out-of-memory condition?
>  If its a command line compiler, it should print "out of memory" and exit.
>  If its a GUI based compiler, it should print a diagnostic (if possible),
>  abort the compile, and *NOT EXIT*.

My point was slightly different.  I've never seen a compiler which
executed directly from a GUI, and I would be very sceptical of such a
case.  A compiler -- that is, the program which actually translates your
source code into some internal format -- is generally a series of
programs, each of which is started by a driver program.  If the driver
program is part of a GUI, or at least, if it is the main part, then it
should not fail.  If the driver interprets the command line to activate
the compiler, it is arguable that it may fail; it is equally arguable
that it should perhaps continue, and try to compile the other modules
you have given it.

Typically, the driver programs are not that complicated; above all,
there are few recursive routines that they are likely to execute.  On
the other hand, a compiler without recursion would be a mighty strange
beast.

> Apparently we are talking about two different 'application spaces'.
>  First, there is the type of application, like a command line
>  compiler.
>  The best it can do with out-of-memory errors is the same thing
>  it does with other "fatal" errors, print a diagnostic and quit.
>  This is a "doit and exit" type program, a tool - generally non
>  interactive.
> My original post neglected to address this first type of application.
>
>  On the other hand, you have applications like word processors,
>  paint programs, spreadsheets, databases, etc...
>  For this type of application, it is *not* acceptable to print a
>  diagnostic and exit.

My point, perhaps not too clearly made, is that there are very view
people writing spreadsheets or word processors.  Most individual
programs do *NOT* do that much; they execute a single command and exit.
Even larger GUI programs should, whenever possible, break down the job
into smaller "commands", which run separately and then terminate.

The "whenever possible" is a limiting factor, I know.  My editor has
syntax highlighting for C++.  Logically, the highlighting should be done
by a separate program, and not the editor itself.  Practically, starting
a new program and giving it all of the information necessary each time
something on the display changes involves too much overhead; the editor
is a monstrous monolith.

>  [James Kanze]
>  >  With regards to the exceptions (the server itself, and most
>  >  non-commercial software, including the systems I work on), what do you
>  >  do when the stack overflows?  For those who think that they are writing
>  >  software to "higher quality of standards than others", read Andy
>
>  My stack doesn't overflow.
>  The OS guarantees me at least a certain amount of stack as part of starting
>  the application.

I think all OS's do.  All of them must give you enough stack to call
main.  And I know of no system in which there is no granularity, which
in practice imposes more.  I know how to force Unix to guarantee me
more, too, although I won't get it until after start-up.

>  I do not have recursive functions which are allowed to recurse indefinitely.

Do you have functions which parse expression like user input, handling
parentheses.  If so, you have two choices: either you impose an
artificial limit (e.g.: 8 levels of nesting), or you leave it open, and
count on being stopped if you run out of resources.  So which is it?

(FWIW: the C standard imposes a minimum of 32.  The current C++ draft
has a "recommended" minimum of 256.  If you use recursive descent, with
one call per precedence level, grabbing enough stack for 256 levels of
nested parentheses, plus the recommended 256 levels of control
structure, at program startup is not being very friendly to other
processes which may need memory.)

>  (Well I might, but I consider it a bug, which will be fixed when found).
>  I have measured the amount of stack the application uses.
>  The only things that affect stack usage are:
>   Function calls (recursive or otherwise)
>   Local variables
>   Processor interrupts.

>  Most importantly: Other apps cannot 'steal' your stack space, like they can
>  steal your heap space.

OS dependant.  Unix officially guarantees neither, but I've yet to see a
Unix implementation in which memory was ever returned to where other
processes can get it.

Whether you want to depend on something which is not guaranteed across
all possible platforms is another question.

>  The first 2 items, the application writer has full control over.
>  For the 3rd item, its up to the OS to guarantee that its not going
>  to put many processor state frames on an applications stack.
>  This is generally true.
>  (Yes I deal with 'allocated' vs. 'committed' stack space. The OS may
>  allocate 500meg of address space for your stack, but until its 'committed',
>  you have no guarantee that you can use it).
>
>  [David Bradley]
>  >  Consider the situation where some other app has sucked all available
>  >  memory and left you with nothing.  You have nothing to free up, what
>  >  do you do?  Even if you are able to free up memory there is nothing
>  >  guarding against the OS handing it over to the other application
>  >  rather than giving it back to you.
>
>  I have considered it.
>  In fact, I have test programs which do exactly this.
>
>  I have tested *every* memory allocation failure path in my application.
>  It recovers from each and every one appropriately.

I agree.  I consider this necessary.  (I use a hacked implementation of
operator new for these tests.  Rather than try and allocate all available
memory, it just declares forfait at a programmable moment.)

I also consider this a strong argument for not trying to continue.  If
the new_handler only displays an error message and aborts, you don't
have very many pathes to validate.

>  In all cases (except where it can't get enough even to start properly),
>  it does *not* exit. It prints a diagnostic (if there is enough memory to do
>  so) and continues. This is possible because for most apps, when they are just
>  sitting there processing mouse events and paint messages, do not need to
>  allocate memory.

Fine for the driver programs.  What is a compiler supposed to wait for?

--
James Kanze           (+33) 88 14 49 00          email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs Bourgeois, 67000 Strasbourg, France
Conseils en informatique industrielle --
                            -- Beratung in industrieller Datenverarbeitung


[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Jeff <jlb@halcyon.com>
Date: 1996/10/15
Raw View
{ Note: followups set to comp.std.c++. -vdv }

J. Kanze wrote:
>
>
> My point, perhaps not too clearly made, is that there are very view
> people writing spreadsheets or word processors.  Most individual
> programs do *NOT* do that much; they execute a single command and exit.
> Even larger GUI programs should, whenever possible, break down the job
> into smaller "commands", which run separately and then terminate.
>
> The "whenever possible" is a limiting factor, I know.  My editor has
> syntax highlighting for C++.  Logically, the highlighting should be done
> by a separate program, and not the editor itself.  Practically, starting
> a new program and giving it all of the information necessary each time
> something on the display changes involves too much overhead; the editor
> is a monstrous monolith.
>

The model you are promoting seems inherently non-portable.  Don't you think
the language and standard library ought to support clean recovery within the
program in a portable way?

Let's go back to your compiler/editor (IDE) example.  Suppose the compiler,
editor and debugger are all executing in the same process and not as separate
programs.  If the compiler runs out of resources while compiling a file it
should be possible for it to throw an exception and assume that the
resources it allocated would be freed during the stack unwind.  This would
be possible if all the objects which hold resources were accounted for on
the stack and if their destructors were properly written.

STL, as it stands, isn't required to be properly written.  That is, it will
leak memory if resources run out when an instantiation of an STL object is
only partially initialized.

This won't handle the running out of stack space problem unless the language
is extended to have an out-of-stack-space exception.  But that's no excuse
for not handling exceptions when other resources run out.

for comp.lang.c++.moderated:
      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]

for comp.std.c++:

[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]