Frequently Asked Questions

How do I find out how much memory my Ice process really uses?

The simple answer to this question is to look at the resident set size using the task manager (under Windows) or the ps command (under Linux). Unfortunately, either way, you are likely to get misleading figures with no practical relevance.

To see why, consider how an operating system such as Windows or Linux allocates physical memory to a process. When the OS starts a process, it initially allocates only a small amount of physical memory to a process (at the very least, one page of memory that contains the instructions at which the process starts executing). As the process runs, it may access virtual memory locations for which the operating system has not allocated a physical page of memory as yet. If this happens, the memory management hardware raises an interrupt (known as a page fault) and transfers control to the OS kernel: in response to the page fault, the kernel suspends the current process, allocates a physical page of memory, initializes that memory with the appropriate text or data, and then resumes the process that caused the page fault. This is known as demand paging. The net effect of demand paging is that the OS does not need to allocate physical memory to a process until that memory is actually needed: if a process never accesses some of its virtual pages of memory, no physical memory is ever allocated for the corresponding pages of virtual memory.

In a demand-paged operating system, it can happen that a process incurs a page fault at a time when all physical memory pages are in use. When this happens, the kernel must choose a page of memory that it can take away from its current process so it can allocate it to the process that caused the page fault. Usually, the page is chosen using a least-recently-used page replacement strategy: the idea is to choose a page for eviction that is unlikely to be used in the near future. However, unless you have a machine that runs a number of large processes, it is quite possible that physical memory actually is never fully in use: with main memory often exceeding a gigabyte, it is entirely possible for all running processes on a machine to actually fit into main memory, so the kernel actually never evicts any physical memory page when servicing a page fault.

If you instrument a process for memory access (pretty much any kind of process will do), you will find that memory access follows the 80/20 rule: a process spends around 80% of its time accessing around 20% of its virtual memory. The 80/20 rule, together with a large main memory size, are responsible for the misleading figures reported by the task manager and the ps command: these tools show the total number of memory pages that are physically allocated to a process, even though most of these pages are touched only once during process start-up and will never be touched again (and could be given to another process without any performance penalty).

What we would like these tools to report instead is the working set size of a process, which is the amount of memory that is used frequently. This number is hard to define because it depends on the exact definition of “frequently”. Intuitively, it is the number of pages of physical memory required by a process to continue running under its normal workload without incurring page faults. Or, in other words, the working set size is the “real” amount of memory that is used by a process while it is running. The difficulty of determining the working set size is the reason why it is not reported by tools such as the task manager and the ps command.

While there is no direct way to measure the working set size of a process, there is a simple trick that you can use to find it, at least under Windows: Windows trims the physical memory pages given to a process to the bare bones when you minimize the window the process runs in. To try this out, take an Ice server and start it in its own command window, and access the server from a client running in another window. Finally, make sure that the client is idle for the time being, so it does not invoke more operations in the server. Now start the task manager and look at the size or your server. Most likely, the task manager will report quite a large figure (around 4MB). Of course, that number includes all the pages that are not really used by the server anymore. Now minimize the window the server is running in. You will see the process size drop dramatically, most likely to less than 100kB, because Windows frees up most of the memory pages that are allocated to the process at this point. Unfortunately, that new number is not the working set size either, because Windows is quite aggressive at freeing memory and ends up removing pages that, in normal operation, would be needed. To get around this, go back to the client and exercise the server again, but do it while the server’s window is still minimized. You will see the process size jump back up again because Windows allocates physical memory pages to the server as it incurs page faults in response to the client activity. That new size gives you an accurate working set size and represents the “real” memory use for your server. (For a minimal server, that size is around 600kB.)

Unfortunately, under Linux, there is no simple trick you could use to determine the working set size because there is no way to coerce Linux into artificially trimming the physical memory allocated to a process—the kernel will remove physical pages of memory from a process only once all physical memory is in use. You can force this to happen by writing a program that allocates an array of memory that is as large as the physical memory of your machine. The program should write at least one byte to every page of the array. You will need super user privileges to run this program because it will most likely require a larger than normal memory limit (see setrlimit(2) or the limit command of your shell). Running this program causes most of the machine’s physical memory to be allocated to it. (It would be polite to not do this on a multi-user machine—using up all available physical memory is a great way to bring a machine to its knees…) If you run the memory-waster program while your Ice client and server are running, per force, the kernel will trim the physical memory of your Ice processes. Now let the memory-waster program exit and use the still-running Ice client to exercise the server. When you now look at the resident set size of the server with ps, you will get a figure that accurately reflects the working set size.

Finally, before you go and give your machine a good work-out in this way, consider simply running your server under Windows and determining its working set size there. Chances are that the Linux figure will be within 20% of the Windows figure, so you can use the Windows working set size as an estimate of the Linux working set size.

Copyright © 2008 ZeroC, Inc.