News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

Raymond Chen on ExitProcess

Started by jj2007, March 07, 2017, 12:10:21 PM

Previous topic - Next topic

jj2007

Radical views from The Old New Thing - Raymond Chen - MSFT January 5, 2012:

QuoteDon't worry about freeing memory; it will all go away when the process address space is destroyed. Don't worry about closing handles; handles are closed automatically when the process handle table is destroyed.
...
The building is being demolished. Don't bother sweeping the floor and emptying the trash cans
...
Okay, if you have internal file buffers, you can write them out to the file handle. That's like remembering to take the last pieces of mail from the mailroom out to the mailbox. But don't bother closing the handle or freeing the buffer, in the same way you shouldn't bother updating the "mail last picked up on" sign or resetting the flags on all the mailboxes. And ideally, you would have flushed those buffers as part of your normal wind-down before calling ExitProcess, in the same way mailing those last few letters should have been taken care of before you called in the demolition team.

I regularly use a program that doesn't follow this rule. The program allocates a lot of memory during the course of its life, and when I exit the program, it just sits there for several minutes, sometimes spinning at 100% CPU, sometimes churning the hard drive (sometimes both). When I break in with the debugger to see what's going on, I discover that the program isn't doing anything productive. It's just methodically freeing every last byte of memory it had allocated during its lifetime.
...
All this anal-rententive memory management is pointless. The process is exiting. All that memory will be freed when the address space is destroyed. Stop wasting time and just exit already.
(note: spelling should be retentive, not rententive)

One of the reasons not to use GlobalFree etc is linked lists (comment January 7, 2012 at 4:42 pm):
QuoteIf it's, say, Raymond's web browser/music player/text editor, keeping a 4 kb block of current state with a pointer to the previous state etc back to the start, you could easily end up with lots and lots of disk thrashing. Each of those blocks will have been paged out – potentially at different times, hence to different bits of the pagefile – at which point every single block will involve a disk seek. That 1 Gb undo/history buffer which seemed so reasonable at the time just became the cause of a quarter-million disk seeks, tying up a typical drive for 20 minutes in the worst case!

what happens during ExitProcess?, Alexey B:
QuoteWhen a process terminates, the following actions occur:

    All threads in the process are halted.
    All the User and GDI objects owned by the process are freed.
    The process kernel object's status becomes signaled.
    The processes code changes to whatever is passed to the function.
    The process' kernel object's usage count is decremented by one.
    The memory containing the code and the memory privately allocated by the process in its address space are freed.

The memory that the system reservers for the process kernel object is not freed until its usage count reaches zero.

No destructors are called. If you use structured exception handling, the __finally statements are not called.

P.S.: See also the November 2015 thread on LoadLibrary, GetProcAddress, FreeLibrary

hutch--

There are 2 things here that don't agree with each other. First quoted text says its OK to slop memory around and rely on ExitProcess to clean up the mess, the second is saying that a badly implemented memory allocation plan will end up thrashing the hard disk that stores the swap file.

There is a solution, write reliable code and clean up on the fly so you don't leave a mess all over the place. The operating system memory allocation strategies all come with their de-allocation procedures so its not as if the OS was designed to leave allocated memory when its no longer used.

There are simple scenarios that make the point, in Win32 you have limited memory, keep allocating 1 gig blocks and see why it fails when previous blocks are left un-allocated. Same effect in Win64 but it takes longer as there is usually more available memory. If a linked list/allocation strategy produces a disk thrashing result, change the design so it no longer doing so.

Unreliable sloppy code will come back and bite you on the arse many times with the OS saying less than nice things about you level of programming competence and shutting your app down.

jj2007

Quote from: hutch-- on March 07, 2017, 12:39:29 PM... rely on ExitProcess to clean up the mess, the second is saying that a badly implemented memory allocation plan will end up thrashing the hard disk that stores the swap file.

Actually, Chen says that de-allocating, i.e. cleaning up (instead of relying on ExitProcess) thrashes the hard disk. The comment on the linked lists explains the problem further.