On 3/6/2012 2:13 PM, Luke Marsden wrote:
[ ... ]
My current (probably quite simplistic) understanding of the FreeBSD
virtual memory system is that, for each process as reported by top:

       * Size corresponds to the total size of all the text pages for the
         process (those belonging to code in the binary itself and linked
         libraries) plus data pages (including stack and malloc()'d but
         not-yet-written-to memory segments).

Size is the amount of the processes' VM address space which has been assigned; the various things you mention indeed are the common things which consume address space, but there are others like shared memory (ie, SysV shmem stuff), memory-mapped hardware like a video card VRAM buffer, thread-local storage, etc.

       * Resident corresponds to a subset of the pages above: those pages
         which actually occupy physical/core memory.  Notably pages may
         appear in size but not appear in resident for read-only text
         pages from libraries which have not been used yet or which have
         been malloc()'d but not yet written-to.

Yes.

My understanding for the values for the system as a whole (at the top in
'top') is as follows:

       * Active / inactive memory is the same thing: resident memory from
         processes in use.  Being in the inactive as opposed to active
         list simply indicates that the pages in question are less
         recently used and therefore more likely to get swapped out if
         the machine comes under memory pressure.

Well, they aren't exactly the same thing. The kernel implements a VM working set algorithm which periodically looks at all of the pages that are in memory and notes whether a process has accessed that page recently. If it has, the page is active; if the page has not been used for "some time", it becomes inactive.

If the system has plenty of memory, it will not page or swap anything out. If it is under mild memory pressure, it will only consider pages which are inactive or cache as candidates for which it might page them out. Only under more severe memory pressure will it start looking to swap out entire processes rather than just page individual pages out.

[ Although, the FreeBSD implementation supposedly will try to balance the size of the active, inactive, and cache lists (or queues), so it is looking at the active list also-- but you don't want to page out an active page unless you really have to, and if you have to do that, maybe you might as well free up the whole process and let something have enough room to run. ]

       * Wired is mostly kernel memory.

It's normally all kernel memory; only a rare handful of userland programs such as crypto code like gnupg ever ask for wired memory, AFAIK.

       * Cache is freed memory which the kernel has decided to keep in
         case it correspond to a useful page in future; it can be cheaply
         evicted into the free list.

Sort of, although this description fits the "inactive" memory category also.

The major distinction is that the system is actively trying to flush any dirty pages in the cache category, so that they are available for reuse by something else immediately.

       * Free memory is actually not being used for anything.

Yes, although the system likes to have at least a few pre-zeroed pages handy in case an interrupt handler needs them.

It seems that pages which occur in the active + inactive lists must
occur in the resident memory of one or more processes ("or more" since
processes can share pages in e.g. read-only shared libs or COW forked
address space).

Everything in the active and inactive (and cache) lists are resident in physical memory.

Conversely, if a page *does not* occur in the resident
memory of any process, it must not occupy any space in the active +
inactive lists.

Hmm...if a process gets swapped out entirely, the pages for it will be moved to the cache list, flushed, and then reused as soon as the disk I/O completes. But there is a window where the process can be marked as swapped out (and considered no longer resident), but still has some of it's pages in physical memory.

Therefore the active + inactive memory should always be less than or
equal to the sum of the resident memory of all the processes on the
system, right?

No. If you've got a lot of process pages shared (ie, a webserver with lots of httpd children, or a database pulling in a large common shmem area), then your process resident sizes can be very large compared to the system-wide active+inactive count.

This "missing memory" is scary, because it seems to be increasing over
time, and eventually when the system runs out of free memory, I'm
certain it will crash in the same way described in my previous thread
[1].

I don't have enough data to fully evaluate the interactions with ZFS; you can easily get system panics by running out of KVA on a 32-bit system, but that shouldn't apply to a 64-bit kernel.

But that's kernel memory, not system VM. What you've described sounds pretty much like a classic load-spiral experienced by pre-forking webservers if you don't constrain the max # of children which can run to something that fits reasonably well without excessive paging, much less swapping.

Is my understanding of the virtual memory system badly broken - in which
case please educate me ;-) or is there a real problem here?  If so how
can I dig deeper to help uncover/fix it?

You've got a pretty good understanding of VM, but the devil is in the details.

Regards,
--
-Chuck
_______________________________________________
freebsd-questions@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-questions
To unsubscribe, send any mail to "freebsd-questions-unsubscr...@freebsd.org"

Reply via email to