September 02, 2006
Serg Kovrov wrote:
> But that not worst part. Although I'm personally from C++ camp and I get used to GC. and see it as good thing. But, there is one big BUT! Currently GC do not return memory to OS, and that thing even I can't subdue. The only reason I choose 'native' (as opposite to VM) programming language is effective resource usage. I hate Java/.net gui applications because their memory consuming. I really appreciate developers that choose c/c++ to write small, memory effective, but yet feature-reach applications like FileZilla Server, uTorrent or Miranda IM.
> 
> Most desktop applications (like text editors, news readers, web browsers, etc) must coexist with each other. That is, to use memory wisely and give it back if it not needed anymore. This 'upper water mark' approach in GC is just not acceptable.

1) Few programmers realize that C/C++'s malloc/free/new/delete *never* (and I emphasize NEVER) return memory to the operating system. All free/delete do is return memory to the memory pool managed by the runtime library, not the operating system. In order to actually return memory to the operating system, one has to write their own memory management code, which is a significant (and necessarily non-portable) effort. Hardly anyone does that.

2) The GC's memory pool doesn't consist of physical memory, it consists of virtual memory. If that virtual memory is not being used, the operating system automatically swaps it out and allocates the physical memory to whoever actually uses it. The 'memory' held by the GC isn't memory at all, but nothing more than a range of addresses.

You can run out of virtual address space, but that's rare and usually indicates you've got a bug, such as an infinite loop allocating memory.

3) The GC could be modified to return unused address space to the operating system, that it doesn't do so now is not a limitation on D itself.

4) Given the exact same code, a gc'd program will consume roughly twice as much memory as the same explicitly allocated one (though neither will return memory to the operating system). But a program written to take advantage of GC can often use less memory (because it needs to make far fewer copies of things, and because it doesn't have to allocate extra memory management blocks like shared_ptr<T> does).

5) malloc/free/new/delete use an 'upper water mark' system of managing their internal free memory pools just like D's gc does.
September 02, 2006
Serg Kovrov wrote:
> If only programmer could have some control over GC, it would be just fine. For example to query GC's memory pool and decide to free some amount if it exceed some threshold. Walter, any comments on this?

Because, as I said in another post, malloc/free/new/delete don't return memory to the operating system, what apps often do if they need to allocate/free some small number of very large buffers is to do them separately, usually with a call straight into the OS API.

You can do the same thing in D, using the same technique and pretty much identical code.
September 03, 2006
Walter Bright wrote:
<snip>
> 1) Few programmers realize that C/C++'s malloc/free/new/delete *never* (and I emphasize NEVER) return memory to the operating system. All free/delete do is return memory to the memory pool managed by the runtime library, not the operating system. In order to actually return memory to the operating system, one has to write their own memory management code, which is a significant (and necessarily non-portable) effort. Hardly anyone does that.
<snip>

Never?  I can't believe you've tried every implementation out there, including your own, and found the same.

Or does the spec forbid free or delete to return memory to the OS?  I can't for the life of me see why this would be.

Stewart.

-- 
-----BEGIN GEEK CODE BLOCK-----
Version: 3.1
GCS/M d- s:-@ C++@ a->--- UB@ P+ L E@ W++@ N+++ o K-@ w++@ O? M V? PS- PE- Y? PGP- t- 5? X? R b DI? D G e++++ h-- r-- !y
------END GEEK CODE BLOCK------

My e-mail is valid but not my primary mailbox.  Please keep replies on the 'group where everyone may benefit.
September 03, 2006
Stewart Gordon wrote:
> Walter Bright wrote:
> <snip>
> 
>> 1) Few programmers realize that C/C++'s malloc/free/new/delete *never* (and I emphasize NEVER) return memory to the operating system. All free/delete do is return memory to the memory pool managed by the runtime library, not the operating system. In order to actually return memory to the operating system, one has to write their own memory management code, which is a significant (and necessarily non-portable) effort. Hardly anyone does that.
> 
> <snip>
> 
> Never?  I can't believe you've tried every implementation out there, including your own, and found the same.
> 
> Or does the spec forbid free or delete to return memory to the OS?  I can't for the life of me see why this would be.
> 
> Stewart.
> 

In general changing the amount a process wishes to use (the data segment size) involves calling [s]brk.  brk just controls the pointer to the end of the memory you have available.  You can't get data segments in chunks, only one contiguous block.  Because of this, it's in general impossible for free/delete to return the memory to the OS, as it cannot move memory arbitrarily (or all the pointers would go funky), and it in all likelyhood has something allocated at the end of the data segment.

I don't know whether it's in any spec that this is how it MUST work, but this is how it USUALLY works.  There's no real reason to do otherwise, especially since changing it would make the data segmentation much more complicated.

 - Gregor Richards
September 03, 2006
On Sun, 03 Sep 2006 01:45:25 +0100, Stewart Gordon wrote:

> Walter Bright wrote:
> <snip>
>> 1) Few programmers realize that C/C++'s malloc/free/new/delete *never* (and I emphasize NEVER) return memory to the operating system. All free/delete do is return memory to the memory pool managed by the runtime library, not the operating system. In order to actually return memory to the operating system, one has to write their own memory management code, which is a significant (and necessarily non-portable) effort. Hardly anyone does that.
> <snip>
> 
> Never?  I can't believe you've tried every implementation out there, including your own, and found the same.
> 
> Or does the spec forbid free or delete to return memory to the OS?  I can't for the life of me see why this would be.
> 
> Stewart.

From memory, I believe the Manx-C for the Amiga used to return memory to the operating system.

-- 
Derek Parnell
Melbourne, Australia
"Down with mediocrity!"
September 03, 2006
Stewart Gordon wrote:
> Walter Bright wrote:
> <snip>
>> 1) Few programmers realize that C/C++'s malloc/free/new/delete *never* (and I emphasize NEVER) return memory to the operating system. All free/delete do is return memory to the memory pool managed by the runtime library, not the operating system. In order to actually return memory to the operating system, one has to write their own memory management code, which is a significant (and necessarily non-portable) effort. Hardly anyone does that.
> <snip>
> 
> Never?  I can't believe you've tried every implementation out there, including your own, and found the same.

You're right, I haven't tried every implementation, and don't know it for a fact. It's just true of every one I've looked at, and there are 3 good reasons for it to be so:

1) Speed
2) Speed
3) Speed

<g>

If your app isrelying on free/delete returning memory to the operating system, you really need to take a good hard look at the implementation of it, because it isn't.

Ironically, it's much more likely that a gc will return memory to the os - because a gc can be a copying collector, meaning it can compact the used memory and free the rest. free/delete cannot do any compaction, meaning it's unlikely to be able to release any memory back to the os due to fragmentation, minimum page sizes, and the high water nature of allocating memory to a task.

It's often moot anyway, since as I wrote before, runtime heap management  is holding on to virtual memory, not physical memory. A gc again has the potential advantage here, as it can compact the actual used memory into as few pages as possible, reducing physical memory consumption, and increasing the working set that will fit into the cache.

> Or does the spec forbid free or delete to return memory to the OS?  I
> can't for the life of me see why this would be.

The spec has nothing to say about it.
September 03, 2006
Walter, thanks for your kind and comprehensive answer, but I still do not get this 'malloc/free do not return memory to OS' part.

I just tried simplest example with GCC(mingw): I allocated with 'new' 1Mb string. Then in process explorer (or in FAR's Process list) I can see my process usage of 'Private bytes' increases equivalently. When free this string, with 'delete', i see that 'Private bytes' usage dropped to same level it was before. Isn't this mean that memory returned to OS?

And second example, I just tried open text files of different size with Catch22 Neatpad example (http://catch22.net/tuts/ - compiled with VC++2005), and see exactly same  behavior. Private bytes usage changes proportionally to opened file size. I've looked at source code an can see that for file buffer and support buffers allocation/deallocation used new/delete from standard library.

Could someone please, explain me where I do not understand Walter? Or maybe point to appropriate article/reference.

-- 
serg.
September 03, 2006
Stewart Gordon wrote:
> Walter Bright wrote:
> <snip>
>> 1) Few programmers realize that C/C++'s malloc/free/new/delete *never* (and I emphasize NEVER) return memory to the operating system. All free/delete do is return memory to the memory pool managed by the runtime library, not the operating system. In order to actually return memory to the operating system, one has to write their own memory management code, which is a significant (and necessarily non-portable) effort. Hardly anyone does that.
> <snip>
> 
> Never?  I can't believe you've tried every implementation out there, including your own, and found the same.
> 
> Or does the spec forbid free or delete to return memory to the OS?  I can't for the life of me see why this would be.

Memory can only be allocated and freed in pages, and a memory page can obviously only be returned to the OS if it is completely empty.  Not to mention the issue of holes in what is typically supposed to be a contiguous address space.  Some allocators will re-purpose empty pages if a different allocation size is needed, but I don't know of any that actually return memory to the OS.  I think huge allocations may be an exception, as allocators typically obtain the memory for these in a slightly different manner.  But even then I'm not sure the memory is "returned to the OS" on release in a manner that would actually decrease the process virtual memory footprint.


Sean
September 03, 2006
Serg Kovrov wrote:
> Walter, thanks for your kind and comprehensive answer, but I still do not get this 'malloc/free do not return memory to OS' part.
> 
> I just tried simplest example with GCC(mingw): I allocated with 'new' 1Mb string. Then in process explorer (or in FAR's Process list) I can see my process usage of 'Private bytes' increases equivalently. When free this string, with 'delete', i see that 'Private bytes' usage dropped to same level it was before. Isn't this mean that memory returned to OS?

Not necessarily. There's a difference between physical memory and virtual memory. The OS will automatically take away from the process any unused physical memory, although the process retains it as virtual memory. If the process explorer watches physical memory, then that's what it's seeing.
September 03, 2006
Walter Bright wrote:
> Serg Kovrov wrote:
>> I just tried simplest example with GCC(mingw): I allocated with 'new' 1Mb string. Then in process explorer (or in FAR's Process list) I can see my process usage of 'Private bytes' increases equivalently. When free this string, with 'delete', i see that 'Private bytes' usage dropped to same level it was before. Isn't this mean that memory returned to OS?
> 
> Not necessarily. There's a difference between physical memory and virtual memory. The OS will automatically take away from the process any unused physical memory, although the process retains it as virtual memory. If the process explorer watches physical memory, then that's what it's seeing.

I'm not trying to argue here, but to understand. I done some search on subject of memory usage. So far, I see it as I described before - to measure application's memory usage, best way is to watch 'private bytes' counter in Perfmon (or via other tools that (I believe) uses Perfmon, such as Process Explorer or FAR's Process list plugin).

For example, quote from http://shsc.info/WindowsMemoryManagement:
> ... is what's called "private bytes" by the Performance control panel.
> It's memory that's private to that process; generally it's the amount
> of RAM the process has asked for in order to store runtime data.

And as I said before C++'s 'delete' (not sure about all implementations, but at least GCC/mingw and VC++2005) do free memory from this 'private bytes' thing.

You said it is not really returned to OS, but get in to some pool. Ok, could you explain further, is it my application's pool, or some shared pool?

What I mean, is: my application allocated and used this memory, but not anymore - it has been 'delete'd. Application will not need a new memory from OS for some time, or even possibly never. Can this freed(deleted) memory be used elsewhere? Please note, I talking about mentioned here C++ implementation that actually affect 'private bytes' counter.

Thanks
-- 
serg.