jstern@garnet.berkeley.edu (05/08/91)
A while back I posted to this group asking for help with a memory problem. It turned out that my problem was one bad xcmd. However, since I had found it frustrating that there was so little information out there about memory, and since I got help from Kevin Calhoun (jkc@apple) and George Harrington (gort@cup.portal.com), and since I got a few requests to pass on whatever I learned, I'll summarize here. TIPS ---- First, there are simple, generally agreed upon things that are you can do if you're having memory problems: 1) Ram Cache: make sure it's off 2) Use finder rather than multifinder, if you can. 3)If running under multifinder, allocate more memory to HC 4) If having problems using painting tools in a particular handler, try and rewrite your code so that the handler is small. Though this seems to be common knowlege, I appreciated an explanation: "As hypercard runs, when it begins to execute a handler, it checks to see if the script has been compiled. If it has not, it then attempts to compile it. If there is not enough memory left to compile the script, hypercard then flushes some of the compiled handlers from memory (provided they are not currently running) and then compiles. If the handler that calls the painting tools is large, it is not purgable (since it is still running) and could prevent hypercard from grabbing the 300k or so extra from the heap that it needs for the painting tools." (George) 5) Buy additional memory (If you're like me--working in a public school--this is not really a sol'n, but it might be for other folks) George had a couple more that I hadn't heard before: 1) If running under multifinder, in addition to allocating more memory to HC, allocate less to the finder (but don't go under minimum recommended amount) 2) Use System 6.0.5, because: "If you are using 6.0.7 or later, this could be a problem,as there seems to be a memory management problem with them. This includes the not publicly released versions of system 7. Even if doing nothing, the heap continues to grow, and eventually will cause the system to bomb (this takes several hours if idle)." And Kevin mentioned a HC bug: "Does the problem ever occur on your machine, when you have read/write access to the stacks in use? If it only occurs when HyperCard has read-only access to the stacks in use, it's possible that you've been bit by an obscure 2.0 bug we've recently found and fixed.The bug occurs when you put a read-only stack in use and then go to and from the stack many times." GLOBALS,STACKSINUSE,XCMDS ------------------------- In my original post, I asked which of three things (lots of globals, lots of stacks in use, or xcmds) was likely to be causing a problem. Though in my case it was definitely an xcmd, here's what I found out about each: GLOBALS: George wrote: "40 [globals] is a lot, and they do take up memory; even filling them with empty, they will still take up space in the name table." STACKSINUSE: No real response about this, except suggestions to combine stacks if possible (wasn't possible in my case--each was already full). XCMDs (and XFCNs): Yes, these can be very dangerous. An xcmd can forget to deallocate space when done. One thing to do is to test any suspect xcmds: on testxcmd xcmd,count if count is empty then put 100 into count put the heapspace into startspace repeat count times do xcmd end repeat put (startspace - the heapspace) div 1024 & "K change in heap space" end testxcmd (I experimented and actually looked at the byte change in heapspace --i.e. didn't "div 1024"--, but I think that's not necessary: I did get byte -- around 40 bytes- changes for X's that are considered very reliable --e.g. Dartmouth XCMDS. In other words, don't worry about little changes; they're probably just caused by the script running.) If you get significant changes you may have a memory leak which "occurs when a piece of code that executes repeatedly allocates memory but doesn't deallocate it. Every time it runs, you lose another block of memory. Eventually, you run so low on memory that the rest of the program can't function properly." (Kevin) However, there seems to be another type of problem, the kind that I had: You run an XCMD once, heapspace is still plenty big, and yet you don't have enough memory to use the painting tools. It's obviously a "bad" xcmd, but doesn't seem to be causing a true memory leak, as described by Kevin. HEAPSPACE --------- Finally, if you'd like to know what heapspace really is, you get to choose from 2 different answers: 1) Actual Contiguous Space "the heapspace is the size of the largest contiguous block of memory currently available to HyperCard. Not the total amount of memory, but the size of the largest unused block of it." (Kevin) "the HeapSpace function typed into the Message Box can tell you approximately how much contiguous space there is in the heap zone of memory." (p. 644,Danny Goodman's Complete HyperCard 2.0 Handbook) or 2) Potential Contiguous Space "The heapspace function returns the maximum contiguous amount of space in the application heap in bytes that would be available if all purgeable handles were purged and all relocatable handles were relocated." (p.417, HyperTalk 2.0, The Book, Winkler & Kamin) "...while you may have plenty of heapspace, there may not be enough contiguous space available to allow the paint tools to run. If you've got 1.4 meg heapspace and still can't paint, the heap sounds like it's badly fragmented." (George) You choose. The second one seems to make slightly more sense in light of my problem (lots of heapspace, not enough memory); but, then again, it seems that the Heapspace isn't of much value if it doesn't tell you what's really out there... Judy Stern