Re: Fastcode MM Challenge B&V 0.07

From: Thorsten Engler [NexusDB] (thorsten.englerNO_at_SPAMnexusdb.com)
Date: 11/18/04


Date: Thu, 18 Nov 2004 14:29:24 +1000


> For instance, if I allocate 10 MB of RAM, then return to the OS pages
> of 16 kB every 20 kb (thus interleaving 4k ME - 16 kb OS - 4kb ME -
> 16kb OS...), my reported usage will be of 2 MB, but the 8 MB I
> returned to the OS
> are so fragmented they are practically useless.

Windows tracks address space in 64kb blocks, not 4kb pages. If you use
VirtualAlloc to reserve address space the start and end address are always
rounded down/up to the next 64kb step. You can commit physical memory in 4kb
pages for the address space you reserved. Windows, using a virtual memory
system, maps each 4kb page of address space to a specific 4kb page of
physical memory. Memory that appears to be continuos in the virtual address
space of a process can come from all over the physical memory. The pages of
physical memory that are owned by a process at any point in time are called
the "working set" of that process. The OS will map these physical pages to
virtual addresses as required. swapping out to and in from the swap file as
necessary, discarding page contents if it's a memory mapped file (e.g. part
of an exe or dll mapped into the address space that hasn't been changed),
and so on. The concept of "memory fragmentation" doesn't exist at the OS
level. A 20MB allocation using VirtualAlloc does NOT need a continuos 20MB
area of physical memory. If I reserve a 10MB area of address space, and then
commit/decommit individual pages within that area that's fine. If, instead,
I reserve a lot of 64kb blocks of address space... and not just
commit/decommit the pages within, but free the blocks back to the OS the
*address space* will get fragmented, not the *memory*. To get back to your
example above, if I reserve 10MB of address space, then commit it all, then
decommit 3 pages every 4 pages. The OS will be able to use these pages I
just returned to the working set just fine, because they aren't continuos
blocks of physical memory in the first place, instead they are just
individual pages somewhere in physical memory. Even more, if I commit that
10MB, and never touch these addresses, the OS hasn't even mapped these
virtual pages to physical pages yet, it just marked them as being
"committed, empty" and the first time you read/write from a page in that
address space the OS will get a fresh page of physical memory from either
the "zeroed pages" list or, if that one is empty, take one from the
"standby" list and zero it, or, if that one is empty too, swap out a page
(of this or any other process), zero it, and map that page of physical
memory to the virtual address in your address space. These 8MB of *memory*
you returned to the OS are not useless, they just go back into the unused
pages list and a background kernel thread will later pick them up, zero
them, and put them in the zeroed pages list for reuse. What happens with
these 8MB of *address space* is a different matter and depends entirely on
the internal implementation of the memory manager, as long as the memory
manager will be able to make use of that address space later without a
problem and commit these pages again and do something useful with them it's
not a bad thing if the memory manager holds on to the address space.

If there is "fragmentation" inside a chunk of reserved address space that
has a negative impact on the operation of the memory manager or not is
something that can't really be determined by just looking at how much
address space is currently reserved in the process. NexusMM for example
reserves/frees 1MB chunks of address space, commits/decommits 64kb blocks of
memory inside these chunks and allocates/disposes items (all the same size
per block) of various sizes from these blocks. This is very effectively
prevents actual fragmentation. There is a slight delay before empty blocks
are decommited and before empty chunks of address space are returned to the
OS because this is done by a background thread. This is the central reason
why it appears that NexusMM is using more address space then e.g. FastMM.
The whole point of it tho is to *reduce* the actual address space
fragmentation that might take place otherwise. e.g. NexusMM might currently
have reserved 50 1MB chunks of address space in a continuos area. If it
would instantly return empty chunks of address space to the OS there is a
pretty good chance that a VirtualAlloc call for e.g. 768kb from somewhere
outside the memory manager (e.g. from loaded DLLs which use their own memory
manager) could be placed in that 1MB slot that was given back to the OS.
When NexusMM later needs more address space it would have to reserve this
1MB chunk somewhere else, leaving a unusable hole of 256kb address space
behind somewhere.

Because of all this I think that using neither peak reserved address space
nor average used address space over time as just a single number as part of
the score is not a good idea.

> Thus aggressively returning memory to the OS can make an MM look good,
> while in practice, the virtual memory it returns won't really be
> usable by other applications, and we don't want to incite that
> practice, do we? ;)

"Other applications" just need pages of physical memory, these pages are
scattered all over the physical address space anyway and are mapped on a
page by page basis into the virtual address space of whatever application
currently needs them. There is nothing that your process can do that somehow
does something to the memory that will affect how other applications can use
it. The worst thing that can happen is that a memory manager will fragment
the *virtual address space* inside the process it runs in. To the point that
it's no longer possible for the OS of finding enough continuos address space
to fulfil a VirtualAlloc call, either because the memory manager never
returned the address space at all (e.g. like HPMM) or because it returned
the address space in so many small fragments that no large enough continuos
areas are left (external fragmentation, we can track that without knowing
implementation details of the memory manager). If the memory manager didn't
return the address space at all it's possible that it's either written in a
way that it never tries (e.g. HPMM again) or that the individual items
allocated from that memory are so fragmented that the MM wasn't able to
return the address space (e.g. BorlandMM) (internal fragmentation, we have
no way to measure that without knowledge of the internal structures of the
MM)

> A workaround for this would be that instead of measuring the memory
> usage, we could measure how much "usable" virtual memory is left, for
> instance by summing up all contiguous free VM areas larger than one
> megabyte.

That makes more sense that just tracking the total used virtual address
space (we should get our terminology straight in regards to "address space"
and "memory", I normally use the later term to refer to committed pages).

Cheers,
Thorsten Engler [NexusMM Architect]



Relevant Pages

  • Re: Fastcode MM Challenge B&V 0.07
    ... just as much as program's memory fragmentation. ... header) GB of address space are reserved for kernel usage and code running ... VirtualAlloc to reserve/commit individual 64kb blocks) will require a lot ...
    (borland.public.delphi.language.basm)
  • Re: RAM
    ... For applications that are I/O-intensive, ... The 4GT RAM Tuning feature increases the memory ... more than 2 GB of physical memory. ... VirtualAlloc function. ...
    (alt.os.windows-xp)
  • Re: Explorer unresponsive
    ... Jeff Stanton wrote: ... boxes before Peak Memory Usage and Virtual Memory size. ... Volume fragmentation ... Event Viewer: Event Type: Error ...
    (microsoft.public.windowsxp.basics)
  • Re: Explorer unresponsive
    ... Jeff Stanton wrote: ... boxes before Peak Memory Usage and Virtual Memory size. ... Volume fragmentation ... Event Viewer: Event Type: Error ...
    (microsoft.public.windowsxp.basics)
  • Re: Watching Virtual Memory
    ... where the undo feature will hold large amounts of information in memory ... files are often not easily defragmented by Disk Defragmenter. ... Is System Restore monitoring your D and E drives. ... Volume fragmentation ...
    (microsoft.public.windowsxp.general)