From: "M. Edward (Ed) Borasky" Date: 2007-10-20T00:29:05+09:00 Subject: Re: [OT] Re: Should *most* memory be release back to the system? khaines@enigo.com wrote: > On Fri, 19 Oct 2007, M. Edward (Ed) Borasky wrote: > >> fork() (or clone() in Linux) is cheap ... it's actually >> *instantiating* the thread or process that costs! Depending how smart >> your kernel is, you could > > This is just a side note, but the sentence above reminded me of it. > > Some time ago I wrote a Mongrel variation that used fork() on incoming > requests instead of spawning a thread. Throughput on it was lousy, > comparatively. Somewhere around an order of magnitude worse than using > Ruby threads. > > It would work for modest volume sites, but there was a large response > time tax imposed by forking versus using the Ruby threads. This was > tested on a Linux box, though it was an older (2.4.x kernel). > > > Kirk Haines > > > Yeah ... I should have been more explicit. When you do a fork/clone in Linux, an "empty" process/thread is created. You get a task control block and an empty memory map and that's about it. That doesn't take very much time or space. But when you actually want that process/thread to do something, its code (text) pages have to be given page frames and loaded into RAM, which I called "instantiating". And those code pages refer to data pages and *those* have to be given page frames in RAM, they read data from disk and *those* pages have to be given page frames in RAM, etc. That's "demand paging" -- nothing happens until an instruction gets a page fault, unless you count the kernel's lookahead mechanisms. In the high-level view, most "modern" operating systems -- Solaris, Windows, Linux and BSD/MacOS -- work the same way. There are minor variations on what things are called and various tuning knobs, but essentially you have pages on disk, page frames in RAM, page-fault-driven on-demand movement of code and data into RAM and some background processes/daemons/kernel threads that try to maintain a balance of all the many demands for page frames. When it works, it works well, and when it doesn't work, it fails spectacularly -- disk thrashing, out-of-memory process killers, response times on the order of minutes for one-second tasks, freezing screens, etc. And the solution is to add more RAM or have the software use less RAM. Now the killer is this: the platform (hardware and OS) designers make a bunch of compromises so that you can get "acceptable" performance for a lot of different languages -- compiled or interpreted, static memory allocation or dynamic memory allocation, explicit memory allocation/deallocation or garbage collection, etc. And the language designers make a bunch of compromises so that you can get "acceptable" performance on modern operating systems. It's almost as if the two types of designers communicate with each other only every fifteen years or so. What's even more interesting is that proposals to change this -- to integrate language design and platform design -- almost always fall back to an experiment that was tried and failed (commercially, not technically): Lisp machines. :)