Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

Let's consider a fictional program that builds a linked list in the heap, and at the end of the program there is a loop that frees all the nodes, and then exits. For this case let's say the linked list is just 500K of memory, and no special space managing is required.

  • Is that a wast of time, because the OS will do that anyway?
  • Will there be a different behavior later?
  • Is that different according to the OS version?

I'm mainly interested in UNIX based systems, but any information will be appreciated. I had today my first lesson in OS course and I'm wondering about that now.

Edit: Since a lot of people here are concerned about side effects, and general 'good programming practice' and so. You are right! I agree 100% with your statements. But my question is only hypothetical, I want to know how the OS manages this. So please leave out things like 'finding other bugs when freeing all memory'.

share|improve this question
15  
I had a program once that re-sorted a linked list 7 times, and then tried to deallocate it. The sorting took 2 hours, but the deallocation took 4 hours because all the sorting has blown any locality of reference. I sped up my program 200% by leaking the memory :D –  MSalters Mar 19 '12 at 15:42
1  
@MSalters: Assuming C++ or C, you could also have allocated from a (per-list) pool. That would allow you to deallocate all of the nodes in one go, regardless of how they might refer to one another. –  Jon Purdy Mar 19 '12 at 18:58
2  
Raymond Chen wrote about this recently. Pretty sure this is Windows specific, but still a relevant. –  R0MANARMY Mar 19 '12 at 19:50
1  
@JonPurdy: I considered that, then decided that writing a pool allocator was a lot harder than calling TerminateProcess. Process memory already is a pool. –  MSalters Mar 20 '12 at 8:31
show 1 more comment

16 Answers

My main problem with your approach is that a leak detection tool (like Valgrind) will report it and you will start ignoring it. Then, some day a real leak may show up, and you'll never notice it because of all the noise.

share|improve this answer
31  
@Vilx: Any difference in execution between debug and release mode can cause you extremely annoying problems, should something go wrong. –  David Thornley Mar 19 '12 at 15:34
1  
If there is a leak and you never notice it, then it's not a problem. The goal is not to create a perfect program, the goal is to create a program that the end user will like. –  Andreas Bonini Mar 19 '12 at 19:58
1  
@fast program vs safe program: does deallocation need so much time? I'd rather think it takes a very small portion of a program's running time. –  Giorgio Mar 21 '12 at 19:48
show 4 more comments

Once I had to implement an algorithm using deques which were allocated dynamically. I was also wondering whether I needed to deallocate all the allocated data at exit.

I decided to implement the deallocation anyway and found out that the program crashed during deallocation. By analysing the crash, I found an error in the implementation of the main data structure and algorithms (a memory leak).

The lessons I learnt were:

  1. Always implement deallocation for the data you allocate, this makes it more reusable in case you want to embed your code in a larger system.
  2. Deallocation can serve as an additional check that your allocated data is in a consistent state when it is released.

Just my 2 cents.

EDIT

Small clarification: Of course all memory allocated to a process gets released when the process is terminated, so if the only requirement is to release the allocated memory, doing it explicitly is indeed a waste of time.

share|improve this answer
add comment

The cleanup routine may be useful if you do it periodically to regain space, or to prove that you are able to reclaim exactly as many nodes as you allocated, to verify that there are no memory leaks. But as housekeeping immediately before the process dies, it makes no sense, since the OS regains control of that entire arena of memory at that instant.

share|improve this answer
add comment
up vote 6 down vote accepted

OK, I just got an Email back from my instructor, with a very good and reasonable answer. Here it is:

Hi Martin,

Thanks for the link to the interesting messages thread which you started.

As per our discussion, malloc operates on the process' virtual memory. So, when the process dies, its virtual address space "disappears", and any physical memory mapped to it is freed. Hence, disregarding "good software engineering practices" and such, dynamic memory de-allocation just before exiting a process is indeed a waste of time.

(Needless to say, this is not the case when a single thread terminates but other threads of that process keep executing.)

So according to this:

  • It is a waste of time
  • Will have no later affects
  • Is independent of OS versions.
share|improve this answer
1  
@Martin If you are only interested in an OS point of view I think it is off topic. Since you got the answer that you were interested in, maybe you should have selected an answer that was more appropriate for the platform. –  scarfridge Apr 23 '12 at 19:16
show 2 more comments

Will there be a different behavior later?

There is a critical question related to this one that you need to ask:

Will anyone ever use this code ever again for any reason?

If the answer could ever be yes, whether the code is used alone or as a part of a larger system, you have created a monumental memory leaking landmine for the next person to step on.

It is very hard to remember during your coursework that you are learning how to make software that other people are going to use including future-you (rather than just solving the homework problem of the day). This means that you need to abide by certain basic programming behaviors including: give back the resources when you are done with them.

share|improve this answer
show 2 more comments

Always free your resources. Freeing all your resources is important because it's the only way of being able to effectively detect leaks. For the project I'm working on I've even got wrappers around malloc/realloc/free to insert canaries, track statistics, etc; simply to detect problems sooner.

However, except for leak detection, for resources that are freed at exit (not before) it is a waste of time. The OS must be able to free it (e.g. in case the process crashes, or even just freeing RAM used for the process' code); and the OS should be able to free it faster than you can from user-space because the kernel will do "wholesale" rather than "piecemeal", and there's less transitions between kernel and process involved.

Fortunately you don't have to choose one way or another. If you want to make sure your code is correct (and you do), but you also want the best possible performance, then do something like:

#ifndef FAST_EXIT
    free(stuff);
#endif
share|improve this answer
add comment

On multi-user systems, the OS will always free such resources because it would be a security risk if it didn't. Your memory contents might end in someone else's process!

share|improve this answer
4  
In some languages, freeing resources merely means releasing the pointers to the memory areas... the old data will still be present in memory unless you scrub it first. –  Robert Harvey Mar 19 '12 at 15:37
3  
@RobertHarvey: True, but that doesn't matter if you then exit the process. The OS doesn't care which language you used (it's all assembly to the OS anyway) and will scrub the memory regardsless, just to be sure. –  MSalters Mar 19 '12 at 15:40
add comment

Cleanup routines can have bugs just like any other code. A sad sight is a program that does what you want except that it hangs or crashes at exit. General practice is to have code clean up after itself, but memory cleanup at process exit is a case where you don't have to.

share|improve this answer
add comment

The problem is that today it's a linked-list node, and tomorrow, it's a resource the OS can't clean up by itself. Is it fast and safe to leave the OS to clean up heap memory? Yes. But does that make it a good idea? Not necessarily.

share|improve this answer
1  
@Krom Inter-process shared memory. It's not used very often because it's a total PITA if things go wrong. –  Donal Fellows Mar 20 '12 at 13:58
show 1 more comment

If you implement your own data type "linked list" not writing a cleanup routine/deconstructor will give you more headaches in the long run than you might think.

Without cleanup code reusing what you wrote will be much harder since your type cannot be used without taking special care (e.g. never create them in a function or loop, but preferably exclusively in main).

Do yourself and everybody else a favor and just write you list_cleanup or ~List.

share|improve this answer
add comment

If you are 100% sure not other process is referencing you linked list and the nodes therein, OK.

100% is a pretty high number, though. Was your list referenced by some persistence code that's being pooled? Does a UI component still have a handle on it? Anything else?

Memory leaks generally don't happen on purpose.

share|improve this answer
1  
Memory isn't shared by multiple processes. Well, it can, but you have to go out of your way to even allocate it. –  delnan Mar 19 '12 at 15:25
2  
@JBRWilkinson Copy-On-Write is an optimization, and it's only valid because it has no semantic impact. With or without COW, parent and child process do not affect each other's memory after fork(). –  delnan Mar 19 '12 at 17:44
show 1 more comment

Almost always yes. Free shared-memory semaphores and UDP server resources (the OS doesn't know how to notify connected UDP servers that you're done).

share|improve this answer
add comment

I always clean up resources on normal exit. It's a safety check that my resource allocation/deallocation calls are done right. This check has alerted me to hidden bugs on more than one occasion. It's like balancing the books of a business at the end of the day.

There may be edge cases such as @MSalter described in his comment, but even that would generally start me looking at customized memory management, rather than just letting the OS clean up and hoping for the best.

share|improve this answer
add comment

Some C++ GUI libraries leak resources like this. This is not a value judgement, but leaking resources and letting the OS reclaim them is a somewhat common occurrence in "real code."

It's always good practice to clean up though, you never know when you'll want to integrate that tool with something else, and then the work is already done (instead of going into the wayback/ remembering machine and remembering all the spots you intentionally leaked).

In one case we actually found a bug because the deallocation was causing a crash because some other memory bug had overwritten the header that delete uses. So, sometimes it can actually help you to find bugs in other areas to free all your resources (you can find an overrun in the previous block).

share|improve this answer
add comment

One thing to think about:

If your code is in a DLL, then you should clean up for sure otherwise if you assume that your process exit will free the resources then your DLL will not be reloadable.

share|improve this answer
show 4 more comments

Managing memory is the best-practice while taking decision to release it in a context is optimization!

Now the ball is in our court!

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.