On Fri, 5 Jun 2009 02:18:53 -0700 (PDT)
Robert Lehr <robert.l...@gmail.com> wrote:
> 
> The problem was that it was not as fast as I expected it should be
> given that it was using no less than 100% of the CPU on my system.
> (two 3GHz Xeon CPUs [1 core]; 3GB RAM; a beefy workstation).  That
> this was visible in the GUI shows how slow it appeared to me.  Also,
> it was using 700MB RAM (VIRT in top).  Sure - it was "swapped" (I'm
> familiar w/ some of the interpretations of these memory issues) except
> that my system has ZERO swap space.  PMAP showed that 400MB of it was
> heap, too, not libraries or binaries or anything else that we can
> safely ignore.  This was (apparently) real, allocated heap, private to
> the process's address space.
> 
> Additionally, as the simulation ran, the initial RSS of 60MB rose to
> 130MB then stopped.  The VIRT remained constant.  I had expected that
> - however I remained concerned.
> 

Just wanted to add some personal notes about the VMM behavior of Linux
in particular that I've observed while tinkering with JVM and PyPy's
garbage collectors and allocators.

Regarding the VIRT and SWAP numbers, it should be noted that, on Linux,
VIRT is a rough estimate of the amount of virtual *address space* that
the process has actually allocated. Not all of this address space
necessarily has corresponding storage on RAM or swap. The reason
revolves mostly around mmap().

Large allocations (of the sort that GC arenas and pool allocators
typically make) are usually serviced by mmap(), which is very lazy in
Linux.

As it has been described to me, what this means is that in the kernel
there is a reserved "dummy" physical page that's filled with zeros that
all pages in the newly allocated virtual address space are mapped to.
When the application actually faults in the page, only then is it
actually allocated in physical memory by the kernel.

The kernel also "resets" a page into this lazy state (deallocating its
physical memory) when a process copies /dev/zero into it. Many
applications incorporate this knowledge so they can take advantage of
this lazy allocation behavior when running on Linux (several of PyPy's
allocators definitely do). I would be extremely surprised if the JVM
didn't do this as well, because it allows a process to "cheat" on RAM
usage by allocating a big arena of memory up front without actually
consuming that amount of RAM. Then, the app just uses the memory as
needed and lets the kernel/VMM worry about allocation.

The side effect of this is that stuff like top and ps report these
allocated-but-unbacked pages as "swapped" even though they aren't
actually on disk anywhere. When mmap() is used for loading real files
off the filesystem (also a lazy operation on Linux), I believe pages
of the file that have not been faulted into RAM are also reported as
swapped.

Executable images are AFAIK loaded by the kernel with mmap(), and large
images like the JVM almost certainly have many pages that may never be
faulted into RAM when running some kinds of apps. It would come as no
surprise to me if the JVM does some mmap()ing of portions of its own
runtime or other things that may also never get referenced.

As an aside, RSS (resident set size) is an estimate of the size of all
pages available to the process that are currently resident in RAM. This
area I am a little less clear on, but I *believe* this number is also a
bit inflated because it includes pages that are shared behind the scenes
from mmap()ed files.  What top reports as "shared" (I *think*) is
actually restricted to application-requested POSIX shared memory and
doesn't count mmap()'s copy-on-write, sharing-as-an-optimization shared
memory.

Sorry for the length, but I hope this may give some insight--hopefully
I'm not telling you things you already know :)

-Kyle

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to