Re: Memory usage from PID
Re: Memory usage from PID
- Subject: Re: Memory usage from PID
- From: Don Quixote de la Mancha <email@hidden>
- Date: Wed, 16 Nov 2011 10:05:57 -0800
Your memory space is divided into several sections.
The .bss section stores your uninitialized global and static data, as
well as data that is initialized to zero. Actually it is all
initialized to zero, it's just that data is put there and initilized
to zero if you don't initalize it to some other value.
The .data section stores your initialized data.
The .text section stores your program's executable code.
Preceding the .bss section is the "Zero Page". This is a region of
unmapped memory that is meant to make your program crash if you
dereference an nil pointer, or refer to a structure member or array
element by adding an offset to a nil pointer. I _think_ the Zero Page
for 32-bit code on OS X is 4 MB, but I may not remember correctly.
I'm pretty sure it's 4 GB for 64-bit code. That's meant to also cause
crashes when 64-bit pointers have their top 32 bits sliced off so they
can be stored as 32 bits.
There is some stuff at the high end of your address space. I'm not
quite certain, but I think that's where your process environment and
command-line arguments live. The top of your stack is just below
them.
I'm pretty sure the highest available virtual memory address is fixed
by the kernel configuration, but I don't know what it is. A
not-quite-correct but reasonable approximation would be to use some
inline assembly to look at the stack pointer during main(), but I'm
sure there is a better way to do that.
To figure out how much stack memory you're using, take the difference
of the stack pointer in main and the stack pointer during the
invocation of your most-deeply-nested subroutine call. If you can't
tell which routine that is by reading your source, profiling with
instruments can give you all your call chains. However it might not
be easy to determine your maximum stack depth if you use recursive
algorithms whose recursion depth depends a lot on your program's input
data or interaction with the user.
The dynamic memory allocation area lies above your executable code and
below the "break". You're probably looking just for the size of that
range, so you know how much you allocate, but you also want to take
care that your stack doesn't explode if you use recursion, or could be
concerned about large subroutine-local variables.
The sbrk() system call will tell you the value of the break if you
pass it zero as a parameter:
size_t theBreak = sbrk( 0 );
To complicate things a great deal, each of the shared libraries and
frameworks you link to will be mapped into your process' memory space.
Each of them will have .bss, .data and .code sections.
If your program is multithreaded, each of your threads will have its
own stack. I don't have a clue where thread stacks go in OS X.
The Mac OS X kernel xnu is a massive fork of the FreeBSD kernel. To
the extent that the two kernels have something in common, it would be
helpful to read the very clearly written book "The Design and
Implementation of the FreeBSD Operating System" by Marshall Kirk
McKusick and George V. Neville-Neil.
Specific to Mac OS X and quite detailed is Amit Singh's "Mac OS X: a
Systems Approach". It should answer your question, but the details of
memory management in the kernel will be quite out of date, as his book
was written during the Tiger era and so focusses on PowerPC with only
occasional mention of the Intel architecture.
While the internal architecture of the Linux kernel is dramatically
different from xnu's architecture, the hardware memory management is
determined by the the Supervisor Mode - or Ring Zero Mode - of the
Intel Instruction Set Architecture. O'Reilly's "Understanding the
Linux Kernel" has a really good discussion of hardware memory
management of 32-bit Intel CPUs.
One more thing... if you have created any shared memory segments, or
used mmap() to memory map any files other than your executable files,
shared libraries and frameworks that the system maps for you, you will
need to account for those.
What you REALLY want to know, though, is quite likely how much of your
code and data is resident, that is, stored in physical memory rather
than paged out to the VM backing store file, or not yet paged in from
your various executable code files.
To the extent that you don't exceed your process' maximum virtual
memory capacity, you can allocate as much memory as you want, but your
program will perform well if only a little bit of your allocation is
actually resident.
The kernel maintains a bunch of statistics about each user process. I
expect that your resident memory usage will be among those statistics,
but I'm sorry I don't know what system call you use to obtain that
information.
--
Don Quixote de la Mancha
Dulcinea Technologies Corporation
Software of Elegance and Beauty
http://www.dulcineatech.com
email@hidden
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden