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 protected] _______________________________________________ Cocoa-dev mailing list ([email protected]) 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [email protected]
