mike@zorch.SF-Bay.ORG (Mike Smithwick) (05/22/91)
[Attack of the killer poodles!] I am using loads of chip ram and it seems to be fragging pretty badly. So much so that I can't run the program more than a couple of times without having to reboot. I am not running any other programs at the same time so there is no outside interference. Theoretically I should return to the same state as I had before, I am not. Any ideas? mike -- "There is no problem to big that can't be solved with high explosives"-Rush Mike Smithwick - ames!zorch!mike
peter@cbmvax.commodore.com (Peter Cherna) (05/23/91)
In article <1991May21.195251.16477@zorch.SF-Bay.ORG> mike@zorch.SF-Bay.ORG (Mike Smithwick) writes: >[Attack of the killer poodles!] > >I am using loads of chip ram and it seems to be fragging pretty badly. So much >so that I can't run the program more than a couple of times without having >to reboot. I am not running any other programs at the same time so there is >no outside interference. Theoretically I should return to the same state >as I had before, I am not. Do as much as you can to free your resources in the reverse order that you obtained them in. Avoid using FreeRemember(FALSE). Avoid doing Alloc(A);Alloc(B);Alloc(C), ... , Free(B). If you do lots of allocations and frees of a fixed size, try to code up some kind of pool allocation scheme. Make sure you free all your resources. >mike Peter -- Peter Cherna, Operating Systems Development Group, Commodore-Amiga, Inc. {uunet|rutgers}!cbmvax!peter peter@cbmvax.commodore.com My opinions do not necessarily represent the opinions of my employer. "If all you have is a hammer, everything looks like a nail."
dillon@overload.Berkeley.CA.US (Matthew Dillon) (05/23/91)
In article <1991May21.195251.16477@zorch.SF-Bay.ORG> mike@zorch.SF-Bay.ORG (Mike Smithwick) writes: >[Attack of the killer poodles!] > >I am using loads of chip ram and it seems to be fragging pretty badly. So much >so that I can't run the program more than a couple of times without having >to reboot. I am not running any other programs at the same time so there is >no outside interference. Theoretically I should return to the same state >as I had before, I am not. > >Any ideas? > >mike >-- >"There is no problem to big that can't be solved with high explosives"-Rush > >Mike Smithwick - ames!zorch!mike You are absolutely right. If you return all resources and free all memory (that you allocated :-)) you should wind up in basically the original state as far as memory fragmentation goes. Two common problems: (1) your program has side effects, such as creating RAM: files, that leaves memory fragmented. (2) you are not FreeMem()ing all the memory you allocated --- easiest to simply run 1> Avail After each program run (keep in mind that the first time the program is run might have side effects re: external libraries it may open which stick around). Avail should return the same amount of memory free. -Matt -- Matthew Dillon dillon@Overload.Berkeley.CA.US 891 Regal Rd. uunet.uu.net!overload!dillon Berkeley, Ca. 94708 USA
jseymour@medar.com (James Seymour) (05/23/91)
In article <21795@cbmvax.commodore.com> peter@cbmvax.commodore.com (Peter Cherna) writes: :In article <1991May21.195251.16477@zorch.SF-Bay.ORG> mike@zorch.SF-Bay.ORG (Mike Smithwick) writes: ::[Attack of the killer poodles!] :: ::I am using loads of chip ram and it seems to be fragging pretty badly. So much ::so that I can't run the program more than a couple of times without having ::to reboot. I am not running any other programs at the same time so there is ::no outside interference. Theoretically I should return to the same state ::as I had before, I am not. : :Do as much as you can to free your resources in the reverse order that :you obtained them in. Avoid using FreeRemember(FALSE). Avoid :doing Alloc(A);Alloc(B);Alloc(C), ... , Free(B). : But if you eventually F/free() the other two, the three chunks of memory (in the above example) will be coalesced by the o/s, won't they? (Assuming no intervening allocations that haven't been free'd.) In other words, if I run multiple processes, each doing any number of memory allocs in any order, providing they all properly free the memory before terminating, AmigaDOS will coalesce all of the adjacent free'd spaces won't it? May sound like a stupid question, but the way Peter phrased his answer, I had to ask. [I'd RTFM, but it hasn't been published/released yet :-)] : : Peter :-- :"If all you have is a hammer, everything looks like a nail." Every time I see this .sig line, I think of the poor souls that think Windows (tm) is representative of what the rest of us mean by multi-tasking. -- Jim Seymour | Medar, Inc. ...!uunet!medar!jseymour | 38700 Grand River Ave. jseymour@medar.com | Farmington Hills, MI. 48331 CIS: 72730,1166 GEnie: jseymour | FAX: (313)477-8897
peter@cbmvax.commodore.com (Peter Cherna) (05/23/91)
In article <1991May23.114423.11039@medar.com> jseymour@medar.com (James Seymour) writes: >But if you eventually F/free() the other two, the three chunks of memory >(in the above example) will be coalesced by the o/s, won't they? I'm not a fragging expert, but I've always assumed the system was happier if you tried to free things in reverse order. (Intervening processes may make allocations.) It's also a generally good programming practice. >Jim Seymour | Medar, Inc. Peter -- Peter Cherna, Operating Systems Development Group, Commodore-Amiga, Inc. {uunet|rutgers}!cbmvax!peter peter@cbmvax.commodore.com My opinions do not necessarily represent the opinions of my employer. "If all you have is a hammer, everything looks like a nail."
dillon@overload.Berkeley.CA.US (Matthew Dillon) (05/24/91)
In article <21795@cbmvax.commodore.com> peter@cbmvax.commodore.com (Peter Cherna) writes: >In article <1991May21.195251.16477@zorch.SF-Bay.ORG> mike@zorch.SF-Bay.ORG (Mike Smithwick) writes: >... > >Do as much as you can to free your resources in the reverse order that >you obtained them in. Avoid using FreeRemember(FALSE). Avoid >doing Alloc(A);Alloc(B);Alloc(C), ... , Free(B). Why? What's wrong with Alloc(A) Alloc(B) Alloc(C) .. Free(B) Free(A) Free(C) ? -Matt >>mike > > Peter >-- >Peter Cherna, Operating Systems Development Group, Commodore-Amiga, Inc. >{uunet|rutgers}!cbmvax!peter peter@cbmvax.commodore.com >My opinions do not necessarily represent the opinions of my employer. >"If all you have is a hammer, everything looks like a nail." -- Matthew Dillon dillon@Overload.Berkeley.CA.US 891 Regal Rd. uunet.uu.net!overload!dillon Berkeley, Ca. 94708 USA
efb@dvncnms.Devoncnms.Unisys.COM (Edward Bacon) (05/24/91)
In article <21795@cbmvax.commodore.com> peter@cbmvax.commodore.com (Peter Cherna) writes: >In article <1991May21.195251.16477@zorch.SF-Bay.ORG> mike@zorch.SF-Bay.ORG (Mike Smithwick) writes: >>[Attack of the killer poodles!] >> >>I am using loads of chip ram and it seems to be fragging pretty badly. So much > [ ... ] >Do as much as you can to free your resources in the reverse order that >you obtained them in. Avoid using FreeRemember(FALSE). Avoid >doing Alloc(A);Alloc(B);Alloc(C), ... , Free(B). > How about lists of Gadgets? Here is what I do: One routine uses AllocRemember() for the gadget, text and image memory. It calls FreeRemember(TRUE) or FreeRemember(FALSE), if every thing went OK or not (oops I think I just got that backwards ..). When I go to destroy a window I call a routine that starts with the FirstGadget frees it (and associated text or image) memory and then does the NextGadget. Is this cool or in violation of what you advocated? I am sortta allocating chunks of memory for the gadget and then freeing the chunks, but all of the window's gadget memory chunks get freed in reverse order. What is the problem with FreeRemember(FALSE) ?
peter@cbmvax.commodore.com (Peter Cherna) (05/24/91)
In article <886@dvncnms.Devoncnms.Unisys.COM> efb@dvncnms.Devoncnms.Unisys.COM (Edward Bacon) writes: >How about lists of Gadgets? Here is what I do: >One routine uses AllocRemember() for the gadget, text and image memory. >It calls FreeRemember(TRUE) or FreeRemember(FALSE), AllocRemember() does: AllocMem( a little header ) AllocMem( the block you want ) and then puts tracking information into the little header. FreeRemember(TRUE) disposes of the headers and the blocks. FreeRemember(FALSE) blows away all the little headers, and leaves you with a memory map that looks like *----*----*----*----*----*----*----*----*----*---- Where * = free and - = allocated. Sorta looks like Swiss cheese, or the barn in Black Sunday. Theoretically, the worst thing you can do is allocate a bunch of blocks and free every second block. Sounds a lot like FreeRemember(FALSE). It would be better to hang on the the little blocks and use FreeRemember(TRUE) at the end of your program. It would be _even_ better if Intuition used a memory-pool manager from which to draw the Remember-headers. It would be _even_even_ better if Intuition itself stopped using FreeRemember(FALSE) itself, but that's another topic. Peter -- Peter Cherna, Operating Systems Development Group, Commodore-Amiga, Inc. {uunet|rutgers}!cbmvax!peter peter@cbmvax.commodore.com My opinions do not necessarily represent the opinions of my employer. "If all you have is a hammer, everything looks like a nail."
eeh@public.BTR.COM (Eduardo E. Horvath eeh@btr.com) (05/26/91)
I read the RKM Intuition manual at least five times trying to puzzle out the use for AllocRemember() and FreeRemeber(). I always thought I was missing something. Why would anyone want to allocate a large number of memory blocks, and then forget what they allocated? What is the reason for FreeRemeber(FALSE) ? -- ========================================================================= Eduardo Horvath eeh@btr.com ..!{decwrl,mips,fernwood}!btr!eeh "Trust me, I am cognizant of what I am doing." - Hammeroid
ahh@glyph.kingston.ny.us (Andy Heffernan) (05/26/91)
In article <21838@cbmvax.commodore.com> peter@cbmvax.commodore.com (Peter Cherna) writes: >In article <1991May23.114423.11039@medar.com> jseymour@medar.com (James Seymour) writes: >>But if you eventually F/free() the other two, the three chunks of memory >>(in the above example) will be coalesced by the o/s, won't they? > >I'm not a fragging expert, but I've always assumed the system was >happier if you tried to free things in reverse order. (Intervening >processes may make allocations.) It's also a generally good programming >practice. Well, sorta. For your typical coalescing memory allocator, given that the heap starts out unfragmented at time t1, and -all- allocations/frees are perfectly nested until time t2, there will be no fragmentation in the heap at any point between t1 and t2. It's not really a heap anymore, it's a stack. Given that nearly all allocations on the Amiga come from the common system heap (AllocMem/FreeMem), however, maintaining perfect nesting of allocations is clearly impossible. Performing allocations from a per-process memory pool (a la sbrk()/malloc()) allows a process total control over its heap and helps to localize any eliminate fragmentation. At any rate, if between t1 and t2 (same initial conditions as above), n random tasks madly allocate and free memory from the system heap in any order, but all memory is guaranteed to have been freed by t2, there should be no fragmentation at time t2. If there is, either the coalescer has a bug or not everything has actually been freed. -- ------------------------------------------------------------------------- Andy Heffernan 文字 uunet!glyph!ahh
ken@cbmvax.commodore.com (Ken Farinsky - CATS) (05/28/91)
In article <2885@public.BTR.COM> eeh@public.BTR.COM (Eduardo E. Horvath eeh@btr.com) writes: >I read the RKM Intuition manual at least five times trying to puzzle out >the use for AllocRemember() and FreeRemeber(). I always thought I was >missing something. Why would anyone want to allocate a large number >of memory blocks, and then forget what they allocated? What is the >reason for FreeRemeber(FALSE) ? AllocRemember() returns a pointer to the memory block as well as linking the allocation into the remember chain. If you save the pointer to the memory block and call FreeRemember(FALSE), you can then track the memory yourself and later free it with a call to FreeMem(). It is much more efficient to just use AllocMem()/FreeMem() and forget AllocRemember(). -- -- Ken Farinsky - CATS - (215) 431-9421 - Commodore Business Machines uucp: ken@cbmvax.commodore.com or ...{uunet,rutgers}!cbmvax!ken bix: kfarinsky
peter@cbmvax.commodore.com (Peter Cherna) (05/28/91)
In article <2885@public.BTR.COM> eeh@public.BTR.COM (Eduardo E. Horvath eeh@btr.com) writes: >What is the reason for FreeRemeber(FALSE) ? There isn't a very good reason for it. The best reason I can give is based on the way OpenWindow() and OpenScreen() use AllocRemember. Using AllocRemember() allows for easy freeing in case of an allocation failure. Then, when the window or screen or whatever succeeds, FreeRemember(FALSE) is called, which increases the amount of memory available. Of course, it makes freeing the window or screen at CloseWindow()/CloseScreen() time more complex, and it frags memory. So there's not really much use, but remember, the first Amigas shipped with 256K of RAM on board, and they were originally going to have 128K on board, so all those little headers did add up to something. >Eduardo Horvath eeh@btr.com Peter -- Peter Cherna, Operating Systems Development Group, Commodore-Amiga, Inc. {uunet|rutgers}!cbmvax!peter peter@cbmvax.commodore.com My opinions do not necessarily represent the opinions of my employer. "If all you have is a hammer, everything looks like a nail."
markv@kuhub.cc.ukans.edu (05/29/91)
In article <2885@public.BTR.COM>, eeh@public.BTR.COM (Eduardo E. Horvath eeh@btr.com) writes: > I read the RKM Intuition manual at least five times trying to puzzle out > the use for AllocRemember() and FreeRemeber(). I always thought I was > missing something. Why would anyone want to allocate a large number > of memory blocks, and then forget what they allocated? What is the > reason for FreeRemeber(FALSE) ? Well, Alloc/Free remember can be useful for backing out of a long chain of allocations part-way through if you have an error. For instance I had window I built with 30 bazzillion gads and menu items. During the build I used AllocRemember() and did a FreeRemember() if I had a problem. If I suceeded then I called FreeRemeber(FALSE) because all the allocated memory was hanging off my window as the menu strip, gads, etc. So at death time I looped though killing each item. Yeah, sounds dumb and was, but that was the idea between FreeRemember(FALSE). I ended up just FreeRemember(TRUE) after I killed the window. I also wrote my own Alloc/Free to track allocations, and report mismatches in address and size, dangling allocations at program exit, etc. To avoid fragging I put the Remember struct in front of the allocation and allocated one block instead of two. I also have manage my own malloc like private pools use (this greatly helps fragmentation). Really big things (>1K) I allocate directly from the system, these aren't common. Medium things (100-1K) I allocate from a variable size pool, small things (<100 bytes) get rounded up to 100 bytes and come out of a seperate pool. This seperate pool for really small things tremendously cuts fragging since it is these things that come and go so fast and can fragment terrbily (messages, etc). I'm playing with some Alloc/Free replacements for exec.library that do similar things as well as "best-fit" allocation instead of "first-fit". The problem here is it really helps to have a task private tracking pool but doing this on exec.library is tough (almost nobody OpenLibrary()s exec.library). One bit of expirimentation determined that rounding up all allocations to the nearest power of 2 (ie 1K 2K 4K) with a limit on max granualarity (32K works well since it will hold the average bitplane which is one of the largest common come/go allocations) in conjunction with best-fit allocations seems to almost completely eliminate fragging. -- ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ Mark Gooderum Only... ¥ Good Cheer !!! Academic Computing Services /// ¥___________________________ University of Kansas /// /| __ _ Bix: mgooderum ¥¥¥ /// /__| |¥/| | | _ /_¥ makes it Bitnet: MARKV@UKANVAX ¥/¥/ / | | | | |__| / ¥ possible... Internet: markv@kuhub.cc.ukans.edu ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
ben@epmooch.UUCP (Rev. Ben A. Mesander) (05/29/91)
In article <1991May28.162254.31102@kuhub.cc.ukans.edu> markv@kuhub.cc.ukans.edu writes: [...] >I'm playing with some Alloc/Free replacements for exec.library that do >similar things as well as "best-fit" allocation instead of "first-fit". It would be nice to have a memory allocation debugging tool for those of us who are not lucky enough to have an MMU. One thing though; I thought common wisdom was that best fit allocation often produces more fragmentation than first fit allocation. Am I out of date? >The problem here is it really helps to have a task private tracking pool but >doing this on exec.library is tough (almost nobody OpenLibrary()s >exec.library). Well, maybe your program would provide an incentive :-) >One bit of expirimentation determined that rounding up all allocations >to the nearest power of 2 (ie 1K 2K 4K) with a limit on max >granualarity (32K works well since it will hold the average bitplane >which is one of the largest common come/go allocations) in conjunction >with best-fit allocations seems to almost completely eliminate fragging. What do you do with very small allocations? -- | ben@epmooch.UUCP (Ben Mesander) | "Cash is more important than | | ben%servalan.UUCP@uokmax.ecn.uoknor.edu | your mother." - Al Shugart, | | !chinet!uokmax!servalan!epmooch!ben | CEO, Seagate Technologies |