It's not ridiculous. Do you think the OS cleans up after the application so that applications shouldn't need to clean up themselves or to guarantee the stability of the OS? I think the later.
> This idea was not invented in 1995.
No, that's when MS finally got around to using it in one of their OS offerings. It has been around for at least 20 years on other operating systems.
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
If at first you don't succeed, try writing your phone number on the exam paper.
The latter certainly, the former somewhat. Not having to worry about explicitly releasing every page back to the OS is a step forward in simplicity as well as robustness. At a low level this is valuable from an application standpoint (for instance the implementation of malloc doesn't have to worry about re-brking the heap -- and for that matter how DOES a user application "free the stack" anyway?). As I already said, at the C++ level it is mostly irrelevant, since merely reclaiming memory doesn't cause destructors to run, and not having destructors run is simply incorrect.
Last edited by brewbuck; 01-05-2008 at 01:07 PM.
Actually I don't agree with myself there either. I was just seeing what other's might say. I would only do that as a hack, if I was very pressed for time.
To me, I don't see the issue being so much about freeing memory. Freeing memory doesn't take very long, and if it does you're already doing something wrong in how it is allocated in the first place (e.g. too many tiny non-pooled allocations). If destructors take a while to run then it is perhaps related to other work such as deleting temporary files, or notifying other PCs across the network about the program closing.
Sometimes you just have to have your destructors run as they may do necessary things like removing hooks too. Due to the way objects are members of larger objects which themselves might be in a list of other objects blah blah etc it often isn't practical to find only exactly what destructors must be run and somehow run those. For those properly using RAII, it can be far easier to simply destroy everything.
That way things that absolutely have to run at program close can be added anywhere to your program.
I don't think anyone can use the slow program closing argument without profiling to see where the time really is being spent. There's also restoring monitor modes and re-drawing the desktop, paging other programs back into memory etc, that is going to take some unavoidable time anyway even after your program closes.
Last edited by iMalc; 01-05-2008 at 02:08 PM.
My homepage
Advice: Take only as directed - If symptoms persist, please see your debugger
Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"
Elysia, I don't think calling it a 'patch' is really correct. Everything since the 386 (using the Intel line as an example) has had Protected Memory mode built into the CPU, which allows 32-bit OS's to allocate a completely separate virtual memory space to each application. Unlike the Win 3.1 days when a GPF could crash all 16-bit programs that were running, and IPF in 32-bit Windows would only crash the program that caused the IPF. Since Intel provided Windows with a tool to protect separate memory namespaces, they decided to use it. This isn't a patch, it's a new feature that was virtually impossible in earlier CPUs.
No, what I mean is that applications should not rely on the OS to clean up their mess. They should explicitly get rid of resources they acquired.
The OS is there to safeguard for poorly written application (why should WE have to suffer because some programmers messed up when creating a program?) AND to make sure that if a program crashes or dies in some horrible way, it doesn't up the memory and never release it back to the OS - no, it should ensure stability.
Yes. It should clean up application's messes if needs be to protect stability and to protect us from applications, but it wasn't built intensionally for cleaning up the mess of a program - only to protect stability and such.
Except that what you're talking about isn't even possible. Many modern operating systems won't even ALLOW you to give memory back to the OS once you've acquired it. Your program's data size can grow but not shrink.
So how is a user application supposed to release all resources if it's not even possible?
Again, this is different from destructing objects. Freeing memory is only a part of that picture.
So you're saying it would not be safe? I think most people here seem to disagree. If it is safe then it is a benefit. Sure, there is a trade off involved, but Sometimes optimization does win over style.
If one of the features of an application you are developing is the ability to safely suddenly terminate at any time, then it is safe to call exit() at any time to force such a termination. Since the feature is there, one may as well use it to quickly close the application. It's fast and guaranteed to work.How so?
I don't see how it matters if the OS or the app cleans up memory in case of a crash--it's the same.
(And here's another side argument for a later time - a lot of applications actually save settings upon exit, making you lose everything if they crash, which I find very annoying; me, on the other hand, save settings as soon as they're made!)
There is a definite optimization.There is no gain to the optimization of letting the OS do the work (the app is exiting, so the user doesn't have to interact with it anymore!) and it's more error-prone too.
The OS just has to flip a switch to mark the memory free.
Closing the normal way requires stack unwinding (sometimes); destructor calls; calls to free()*, which have to make the memory available to malloc() again, even though the program is shutting down; and only then does the application quit. Then the OS still has to flip the exact same switch to mark the memory free. (Note free() does not generally return memory back to the OS)
*I'm assuming for simplicity that new/delete are implemented in terms of malloc/free. If they are implemented differently, the functionality would still have to be similar, so it doesn't really matter that it goes by a different name.
Agreed here. There are many cases where this optimization would not be suitable.And those are big downsides. ...
And hey... what if the program DOES require interaction when it quits? Bye-bye to the OS patch-up instead of the program.
I'd be willing to consider an argument saying that the optimization is negligible, particularly if evidence was provided. But your argument seems to be most based mostly on stylistic grounds, which take a back seat once optimization kicks in.
It is too clear and so it is hard to see.
A dunce once searched for fire with a lighted lantern.
Had he known what fire was,
He could have cooked his rice much sooner.
I'd say that not calling delete on exit is an optimization hack that should be used very carefully and should be explicitly documented if done.
The only things that should ever be allowed to be freed by the OS instead of using delete are primitive data types or objects which you have total control over and know that the destructor doesn't do anything other than free memory.
Since it is an optimization hack, it should not be used unless there is a serious performance problem during program shutdown that cannot be resolved in any other way. If used incorrectly, this hack could be dangerous and leak resources that don't get automatically cleaned up by the OS.
The thing I think we'll all agree on is that probably in most cases, programs that don't clean up their resources upon exit are the ones that leak like a sieve whilst they're running as well.
My homepage
Advice: Take only as directed - If symptoms persist, please see your debugger
Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"
FYI, if you get memory using new, then free it using delete.
Whether or not it returns to the OS is OS specific and we can't do a darn thing about it - so let's just think about it this way: You call new, then you call delete, and there your responsibility ends. Now it's up to the OS.
It should not be safe. Or should not be possible, or something. Optimization or not, I do not like the idea of doing this at all, for all reasons mentioned above.
And how many programs can safely shut down and does not have some work to do when shutting down? Saving settings, perhaps? It's far better and safer to just shut down the normal way and let all destructors and cleanup code run.If one of the features of an application you are developing is the ability to safely suddenly terminate at any time, then it is safe to call exit() at any time to force such a termination. Since the feature is there, one may as well use it to quickly close the application. It's fast and guaranteed to work.
FYI, I haven't had a single problem where the application takes too long time to shut down as opposed to startup time.I'd be willing to consider an argument saying that the optimization is negligible, particularly if evidence was provided. But your argument seems to be most based mostly on stylistic grounds, which take a back seat once optimization kicks in.
Though typically it's also true that I don't run that much cleanup code since I make sure everything is saved properly the first time it's done (like saving settings), as to safeguard from crashes and unindented computer shutdowns.
But I would never think of purposely not freeing all resources and getting the OS to do it for you.
Once again, I already said that you should delete all objects.
So we should poison the operating system so it explodes if someone does something Elysia doesn't like?It should not be safe. Or should not be possible, or something. Optimization or not, I do not like the idea of doing this at all, for all reasons mentioned above.
Enough "FYI" already. Where the hell have you developed this wellspring of experience anyway?FYI, I haven't had a single problem where the application takes too long time to shut down as opposed to startup time.