Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!swrinde!zaphod.mps.ohio-state.edu!think.com!snorkelwacker.mit.edu!stanford.edu!neon.Stanford.EDU!torrie From: torrie@cs.stanford.edu (Evan Torrie) Newsgroups: comp.sys.amiga.advocacy Subject: Re: what to buy??(numbercruncher) Message-ID: <1991Jun22.075040.27113@neon.Stanford.EDU> Date: 22 Jun 91 07:50:40 GMT References: <1991Jun20.160839.28053@mintaka.lcs.mit.edu> <82@ryptyde.UUCP> <5333@dirac.physics.purdue.edu> <1991Jun21.235106.14465@mintaka.lcs.mit.edu> Sender: torrie@neon.Stanford.EDU (Evan James Torrie) Organization: Computer Science Department, Stanford University, Ca , USA Lines: 86 rjc@wookumz.gnu.ai.mit.edu (Ray Cromwell) writes: > From the way I interpret this, the Mac has some form garbage collection >to prevent memory defragmentation. I wouldn't call it garbage collection in the sense of a language like LISP. It's more a memory compactor. Generally invoked either explicitly (_CompactMem), or when a memory request fails because of fragmentation. >I get the suspicous feeling that >the MacOS was developed originally in a language other than C, something >with a run-time memory manager and garbage collector. Am I right? The MacOS was originally developed with Pascal in mind (as the Lisa had been before it). This means it has the general structure of a heap growing upwards (where dynamic memory is allocated), and a stack growing downwards. Heap space can be allocated using a NewPtr() call, which corresponds to a Pascal new() call. That is, you end up with a non-relocatable block in the middle of your heap. Because you can make copies of this pointer (e.g. myptr = thatptr), and pass them around (in fact, you may have 100s of pointers pointing to this block), it's infeasible to allow such a block to move, since to do so would require updating all these pointers throughout memory. The MacOS adds the concept of handles, a ptr to a ptr. The actual ptr to the block is called the master pointer, and there's only ever one of these. You can make as many copies of the handle as you want, and pass it around, since they all point to the master pointer. Such a block can be easily relocated because the OS has to change only the master pointer, and need not concern itself with all the handles. Unlike LISP, the memory manager doesn't have to go around finding unreferenced blocks of memory when it wants more free space. Instead, the program explicitly tells the OS that the block is unreferenced, via a DisposeHandle call. [There are a few more subtleties than this, like making a block able to be purged, or making it unable to be moved [using HLock], but that's the general idea]. So the idea of handles is to allow blocks of memory to be relocated by the OS at any time, yet still let the program (which may have multiple references to this block of memory) be insulated from the actual location of the block. > 1) Double indirection of pointers is slower > (yes you can lock a memory block, but why use handles in the first place? > I know I would be irritated if I had to constantly do a > ptr1->ptr2->mystuff when coding) How about (*ptr)->mystuff, or (**ptr).mystuff? > 2) garbage collection is expensive and it gets worse depending on > the amount of memory you have and the amount being used The Mac memory compaction depends not on the amount being used, but on the number of different blocks being used. If you allocate little blocks for every single object, and then run into low-memory problems, you can see a slow-down in some applications. What you can do of course, is just allocate a big block for your own private use, and then use your own mem. routines to allocate from within that block. > On modern computers an MMU can be used to defrag memory and private >memory pool managing can reduce it greatly. Can someone tell me >why Apple uses this type of memory management? The 68000 didn't have an MMU. How does the Amiga defrag memory? > It still seems strange that you have to 'limit' or tell the OS >the maximum memory your app will need. This is an artifact of the single application model of 1984. The application started its heap in low memory, its stack in high memory, and they grew together until they collided. With multiple applications, the OS has to start the base of the stack somewhere [at less than high memory], and grow downwards from there, to allow other applications to reside in the same address space. The 'limit' is essentially the application writer's best guess as to how much memory his heap and stack need together before they would collide. As Sho says, this limit can be got around by using temporary memory in MultiFinder's unused memory pool. [In System 7, this is better supported and made more robust than in 6]. -- ------------------------------------------------------------------------------ Evan Torrie. Stanford University, Class of 199? torrie@cs.stanford.edu "Lay me place and bake me pie, I'm starving for me gravy... Leave my shoes and door unlocked, I might just slip away - hey - just for the day."