译者注:最后一句的free will touch and page in the dead objects,我不是很理解,我猜可能是说这些dead objects处于操作系统中某一page,而这个页面因为太久没调用,现在不在内存里面,如果要touch这个objects,就需要把这个废弃页面从硬盘或是其它地方调入内存,又因为马上就要结束程序了,这个操作很明显是多余且浪费性能的。
This has been something that has bothered me for ages now.
有个问题困扰我很久了。
We are all taught in school (at least, I was) that you MUST free every pointer that is allocated. I’m a bit curious, though, about the real cost of not freeing memory. In some obvious cases, like when malloc is called inside a loop or part of a thread execution, it’s very important to free so there are no memory leaks. But consider the following two examples:
/* Do some arbitrary stuff with 'a' (no alloc functions) */ //(随意对a做些操作但不使用任何分配内存的函数)
return 0;
}
What’s the real result here? My thinking is that the process dies and then the heap space is gone anyway so there’s no harm in missing the call to free (however, I do recognize the importance of having it anyway for closure, maintainability, and good practice). Am I right in this thinking?
Second, let’s say I have a program that acts a bit like a shell. Users can declare variables like aaa = 123 and those are stored in some dynamic data structure for later use. Clearly, it seems obvious that you’d use some solution that will calls some *alloc function (hashmap, linked list, something like that). For this kind of program, it doesn’t make sense to ever free after calling malloc because these variables must be present at all times during the program’s execution and there’s no good way (that I can see) to implement this with statically allocated space. Is it bad design to have a bunch of memory that’s allocated but only freed as part of the process ending? If so, what’s the alternative?
Just about every modern operating system will recover all the allocated memory space after a program exits. The only exception I can think of might be something like Palm OS where the program’s static storage and runtime memory are pretty much the same thing, so not freeing might cause the program to take up more storage. (I’m only speculating here.)
So generally, there’s no harm in it, except the runtime cost of having more storage than you need. Certainly in the example you give, you want to keep the memory for a variable that might be used until it’s cleared.
However, it’s considered good style to free memory as soon as you don’t need it any more, and to free anything you still have around on program exit. It’s more of an exercise in knowing what memory you’re using, and thinking about whether you still need it. If you don’t keep track, you might have memory leaks.
On the other hand, the similar admonition to close your files on exit has a much more concrete result – if you don’t, the data you wrote to them might not get flushed, or if they’re a temp file, they might not get deleted when you’re done. Also, database handles should have their transactions committed and then closed when you’re done with them. Similarly, if you’re using an object oriented language like C++ or Objective C, not freeing an object when you’re done with it will mean the destructor will never get called, and any resources the class is responsible might not get cleaned up.
Yes you are right, your example doesn’t do any harm (at least not on most modern operating systems). All the memory allocated by your process will be recovered by the operating system once the process exits.
Allocation Myth 4: Non-garbage-collected programs should always deallocate all memory they allocate.
分配误区4:无垃圾回收机制的程序总是需要回收所有它分配的内存。
译者注:Myth除了神话这个意思外,还有误区的意思,当我知道的时候咂吧了一下嘴。
The Truth: Omitted deallocations in frequently executed code cause growing leaks. They are rarely acceptable. but Programs that retain most allocated memory until program exit often perform better without any intervening deallocation. Malloc is much easier to implement if there is no free.
In most cases, deallocating memory just before program exit is pointless. The OS will reclaim it anyway. Free will touch and page in the dead objects; the OS won’t.
最后一句的free will touch and page in the dead objects,我不是很理解,我猜可能是说这些dead objects处于操作系统中某一page,而这个页面因为太久没调用,现在不在内存里面,如果要touch这个objects,就需要把这个废弃页面从硬盘或是其它地方调入内存,又因为马上就要结束程序了,这个操作很明显是多余且浪费性能的。
Consequence: Be careful with “leak detectors” that count allocations. Some “leaks” are good!
结论:小心这些对分配计数的“内存泄漏探测者”,有的”泄漏”还是不错的!
That said, you should really try to avoid all memory leaks!
也就是说,你的确应该避免所有内存泄漏!
Second question: your design is ok. If you need to store something until your application exits then its ok to do this with dynamic memory allocation. If you don’t know the required size upfront, you can’t use statically allocated memory.
=== What about future proofing and code reuse? ===
=== 校对与复用 ===
If you don’t write the code to free the objects, then you are limiting the code to only being safe to use when you can depend on the memory being free’d by the process being closed … i.e. small one-time use projects or “throw-away”[1] projects)… where you know when the process will end.
If you do write the code that free()s all your dynamically allocated memory, then you are future proofing the code and letting others use it in a larger project.
如果你的确去释放了所有动态分配的内存,那么未来的校对会更加顺利,并且还能将其使用在一个大项目中。
[1] regarding “throw-away” projects. Code used in “Throw-away” projects has a way of not being thrown away. Next thing you know ten years have passed and your “throw-away” code is still being used).
I heard a story about some guy who wrote some code just for fun to make his hardware work better. He said “just a hobby, won’t be big and professional“. Years later lots of people are using his “hobby” code.
近期评论