ideas for returning memory to the OS

"[email protected]" <[email protected]> Tue, 11 Dec 2007 04:06:02 -0800 (PST)
Newsgroups gmane.comp.mozilla.performance
Organization http://groups.google.com
Message-ID <ac77e5fa-c864-4062-816d-f489aa77fcfd@e23g2000prf.googlegroups.com>
So we're doing a bunch of work to avoid allocations, fuse allocations,
and move lifetime-correlated allocations into arenas/subheaps, all to
avoid fragmentation. That's great. But what about returning memory to
the OS? For that we need to unmap memory. Below I wrote some ideas for
doing that. BUT is it really true that we need to unmap memory to
return it to the OS? I don't think it is. In fact all three of our
main platforms have a way to tell the OS that the contents of a
committed page are no longer needed, need not be paged out, so the RAM
can be be used by another process, but without messing around with
munmap and VMA fragmentation!

On Mac: msync(MS_KILLPAGES)
On Windows: VirtualAlloc(MEM_RESET)
On Linux: madvise(MADV_DONTNEED) (MADV_FREE is a slightly better
semantic fit but isn't supported yet)

The main question is, are these already used by platform heap
implementations? If they are, there's really nothing for us to do.
Otherwise, we can use them, fairly easily in the case of our arena
implementation(s).

A secondary question is, do these affect top/Task Manager in a way
that would prevent the "I opened 10 pages and closed them and Task
Manager shows Firefox still using 17 gigabytes of memory" complaints?

===== Probably obsolete idea ======

We don't want to map and unmap small chunks because that leads to VMA
fragmentation which is really bad for performance. So we encounter the
fragmentation problem again at a higher level.

So here's the idea. Create "VM arenas" for lifetime-correlated VM
allocations. Each VM arena has a set of blocks of reserved VM, each
say 1MB in size. (I think on all major platforms we can make a large
VM reservation and ensure the pages are only allocated lazily, say
when the process touches them, so this won't waste RAM or swap.) Then
associate one VM arena with each top-level window. Allocations whose
lifetime is tied to the top-level window --- including chunk
allocations for the content and frame arenas for documents inside the
window --- are made from the window's VM arena. This would ensure that
when the window is destroyed, all that memory can be unmapped,
assuming no objects in the window's arenas are live. (We should track
down any such stubborn objects and have them allocated elsewhere.) But
address space lost due to fragmentation would be limited to some
amount proportional to the number of open windows, and the number of
mmap/munmap operations due to these VM arenas would be limited because
we're working with 1MB chunks. It gives the easy-to-understand
behaviour that closing windows returns memory to the OS.

We could use "tab" instead of "top-level window" to scope the VM
arenas if that makes more sense. And of course 1MB is a tunable
parameter.