ggm@brolga.cc.uq.oz.au (George Michaelson) (10/04/90)
My understanding is that existing brk/sbrk/malloc in generic *nix doesn't allow the process to shrink again once mem has been allocated. Could somebody explain to a non-wizard what stops some method being used to detect free mem pages or compress the heap such that memory CAN be freed? I dont mean "for free" ie explain what would have to be different in HOW malloc/alloc/sbrk/free work to get this behaviour. I'm expecting to be told that keeping back-pointers to entities using allocated memory so you could dynamically update their position if you'd compressed the heap is more pain than it's worth. If thats not the case, I see some attractive uses of grabbing 5-10 Mb of space, using it and then releasing it without having to exit. -George -- G.Michaelson Internet: G.Michaelson@cc.uq.oz.au Phone: +61 7 377 4079 Postal: George Michaelson, Prentice Computer Centre The University of Queensland, St Lucia, QLD Australia 4067.
cpcahil@virtech.uucp (Conor P. Cahill) (10/04/90)
In article <1990Oct3.225943.4691@brolga.cc.uq.oz.au> ggm@brolga.cc.uq.oz.au (George Michaelson) writes: >My understanding is that existing brk/sbrk/malloc in generic *nix >doesn't allow the process to shrink again once mem has been allocated. True. >Could somebody explain to a non-wizard what stops some method being >used to detect free mem pages or compress the heap such that memory >CAN be freed? I dont mean "for free" ie explain what would have to >be different in HOW malloc/alloc/sbrk/free work to get this behaviour. Nothing stops this from being implemented and it would not require a change to the way free() is *allowed* to work. However, some programs depend upon an old free() behavior that says something to the effect that the free'd segment is still available until the next call to one of the allocation functions. Besides that "compatibility" reason, you have to consider the usefulness of that kind of change for the "average" program. What I mean here is what measurable effect would adding that functionality have to the system as a whole? If it is not measurable (like being able to support x% more users with the same amount of memory, or a x% increase in overall system performance) then why do it? Even though free does not actually return the memory to the system, it does mark it for re-use, so your programs do not grow indefinately (unless, of course, you have a bug in your program). >I'm expecting to be told that keeping back-pointers to entities using >allocated memory so you could dynamically update their position if >you'd compressed the heap is more pain than it's worth. Heap compression is a different animal all together. You would run into zillions of problems with programs that got the pointer returned from malloc and copied it elsewhere, etc. To allow for this you would have to require that any access to a malloced area be made through one of your functions that would then do the translation to a real address (sort of your own virtual memory manager). talk about a bad effect on performance. >If thats not >the case, I see some attractive uses of grabbing 5-10 Mb of space, using >it and then releasing it without having to exit. You could probably do with other mechanisms that do not require the jump to 10MB of mem and the fall back to 0, or that use a child program to process the 10MB of data and passes it's output back to the parent and exits (thereby freeing the allocated memory). -- Conor P. Cahill (703)430-9247 Virtual Technologies, Inc., uunet!virtech!cpcahil 46030 Manekin Plaza, Suite 160 Sterling, VA 22170
slb@neptune.dsc.com (Steve Baur) (10/04/90)
ggm@brolga.cc.uq.oz.au (George Michaelson) writes: >My understanding is that existing brk/sbrk/malloc in generic *nix >doesn't allow the process to shrink again once mem has been allocated. >Could somebody explain to a non-wizard what stops some method being >used to detect free mem pages or compress the heap such that memory >CAN be freed? The problem has to do with the fact that generic *nix is basically a swapping system, with virtual memory paging (if it exists at all) added as an after thought. This is true through System V/R3. The UNIX system process data space looks like this: +-------------------------------+ | Process Stack | | | | | V | | | +-------------------------------+ | | | Free Memory | | | +-------------------------------+ <---- "Break" | | | ^ | | | | | Heap | | | +-------------------------------+ | | | BSS | | | +-------------------------------+ | | | Data | | | +-------------------------------+ The line above the heap (called the "break") is adjusted via the brk(2) and sbrk(2) system calls and is adjusted upwards when more memory is needed. It could also be adjusted downwards when allocated memory just below the break is released, but that does not seem to be performed through System V/R3. A more basic problem exists with this scheme though. Imagine allocating a 100k chunk of memory, then a 10 byte chunk of data, then deallocating the 100k chunk. Now the allocated 10 byte chunk of data sits just below the break, and hence it cannot be adjusted downwards to reflect the release of the 100k chunk. No holes are allowed to exist between the top of BSS and the break. Anyway, to properly deal with a paging system, something like a getvmpage/ releasevmpage (that treats virtual memory as pages rather than as an area below an address) is needed. -- "The speed of light ... It's not just a good idea, it's the law." Steve Baur (slb%neptune%dschub@hub.ucsb.edu)
jef@well.sf.ca.us (Jef Poskanzer) (10/05/90)
In the referenced message, cpcahil@virtech.UUCP (Conor P. Cahill) wrote: }In article <1990Oct3.225943.4691@brolga.cc.uq.oz.au> ggm@brolga.cc.uq.oz.au (George Michaelson) writes: }>I see some attractive uses of grabbing 5-10 Mb of space, using }>it and then releasing it without having to exit. } }You could probably do with other mechanisms that do not require the jump }to 10MB of mem and the fall back to 0, or that use a child program to }process the 10MB of data and passes it's output back to the parent and }exits (thereby freeing the allocated memory). The child process idea is good. Another trick that I've used is to have the program restart itself with an "execvp(*argv, argv);" This is for situations when the process's interaction model is "wait for a long time, do something that needs a lot of memory, go back to waiting". For example, a screen saver. --- Jef Jef Poskanzer jef@well.sf.ca.us {ucbvax, apple, hplabs}!well!jef "Do you think we can use battery operated devices under water?"
chapman (Brian Chapman) (10/10/90)
ggm@brolga.cc.uq.oz.au (George Michaelson) writes: >My understanding is that existing brk/sbrk/malloc in generic *nix >doesn't allow the process to shrink again once mem has been allocated. At the system call level brk() and sbrk() allow you to give the memory back to the system. [doesn't it say that on your man page?] The malloc()/free() stuff implemented on top of that in libc.a has traditionally never bothered. Malloc() will brk() for more memory if it needs it but it free() doesn't brk() the level down if you give the memory back. There is no reason for this that I know of except complexity and execution time trade offs. (ie. most people don't care and they don't want free() spending execution time thinking about it) >Could somebody explain to a non-wizard what stops some method being >used to detect free mem pages or compress the heap such that memory >CAN be freed? I dont mean "for free" ie explain what would have to >be different in HOW malloc/alloc/sbrk/free work to get this behaviour. Don't use malloc() and free() just call brk and use the raw address space you allocate. This requires an understanding of the process address space model of your version of Unix. And is a hell of a lot less portable than using malloc()/free(). [Well, OK, I guess it could be done in a portable way, sort of...] >I'm expecting to be told that keeping back-pointers to entities using >allocated memory so you could dynamically update their position if >you'd compressed the heap is more pain than it's worth. If thats not >the case, I see some attractive uses of grabbing 5-10 Mb of space, using >it and then releasing it without having to exit. > -George Yup, malloc() and free() don't work that way, but nothing stops you from implmenting your own system like you describe above on the system call brk() sbrk() interface -- Chapman -- Brian Chapman uunet!sco!chapman Pay no attention to the man behind the curtain!
pcg@cs.aber.ac.uk (Piercarlo Grandi) (10/11/90)
On 3 Oct 90 22:59:43 GMT, ggm@brolga.cc.uq.oz.au (George Michaelson) said: ggm> My understanding is that existing brk/sbrk/malloc in generic *nix ggm> doesn't allow the process to shrink again once mem has been allocated. It depends on what you mean, and the kernel you are working on... ggm> Could somebody explain to a non-wizard what stops some method being ggm> used to detect free mem pages or compress the heap such that memory ggm> CAN be freed? I dont mean "for free" ie explain what would have to ggm> be different in HOW malloc/alloc/sbrk/free work to get this behaviour. Here you seem to imply that for you 'free' means 'freed at the malloc level. Well, almost none of the C heap storage managers will lower the break if this is possible. I have written (and posted to alt.sources) my own malloc/free package that does lower the break if one frees a block of store just under the break. It does not not to compaction of the arena though. There are C/C++ automatic storage reclaimers that use compacting garbage collection; I do not know whether after compaction they lower the break, if possible. If so, it would not be difficult to modify them to do so. ggm> I'm expecting to be told that keeping back-pointers to entities using ggm> allocated memory so you could dynamically update their position if ggm> you'd compressed the heap is more pain than it's worth. Read some papers on garbage collection, especially conservative g.c. in C/C++. The sweeper of a g.c. reclaimer will in one way or another simulate those backpointers. ggm> If thats not the case, I see some attractive uses of grabbing 5-10 ggm> Mb of space, using it and then releasing it without having to exit. Now there is a catch: even if your storage reclaimer detectes that a block of memory just under the break has become free, and lowers the break as a result, in many UNIX kernels this regrettably will not release any pages to the kernel mmeory pool -- in some it will not even invalidate page table entries beyond the break. This is probably because so few C/C++ sotorage reclaimers bother to lower the break, so it is perceived that actually shrinking the data and address space of a process when the break is lowered is not worth its while. -- Piercarlo "Peter" Grandi | ARPA: pcg%uk.ac.aber.cs@nsfnet-relay.ac.uk Dept of CS, UCW Aberystwyth | UUCP: ...!mcsun!ukc!aber-cs!pcg Penglais, Aberystwyth SY23 3BZ, UK | INET: pcg@cs.aber.ac.uk
ggm@brolga.cc.uq.oz.au (George Michaelson) (10/11/90)
Thankyou for all the followups and individual emails. It looks as if there is no guaranteed method of achieving what I wanted, although on some systems there *are* ways of coming close if not all the way. modified malloc sounds closest in being simple to retrofit, and may offer benefit if slipped under existing programs, certainly if large single blocks of space are malloc'ed and freed. I dont think compaction sounds feasible short of a C++ approach providing it in the infrastructure, unless you are prepared to do ALL the ptr management yourself. If you have a way to model some data in a humungous space (eg trying to do data persistance by dumping memory to disk between process invokations) you're probably doing 1/2 of it already. I *did* try R'ing the FM in this area, and must say that on SunOS4.1 at least it is less than perspex clear on brk/sbrk behaviour, at least for anybody not well versed in system internals. Clearly an area fools like me are not meant to tread. Seems a shame, given programs which have transient need for large dynamic data areas but can then become vastly smaller again. What we get from the opsys is simple to implement, but also seems lacking in functionality. -george -- G.Michaelson Internet: G.Michaelson@cc.uq.oz.au Phone: +61 7 377 4079 Postal: George Michaelson, Prentice Computer Centre The University of Queensland, St Lucia, QLD Australia 4067.
chris@mimsy.umd.edu (Chris Torek) (10/11/90)
In article <PCG.90Oct10212600@odin.cs.aber.ac.uk> pcg@cs.aber.ac.uk (Piercarlo Grandi) writes: >Now there is a catch: even if your storage reclaimer detectes that a >block of memory just under the break has become free, and lowers the >break as a result, in many UNIX kernels this regrettably will not >release any pages to the kernel mmeory pool .... (from /sys/kern/vm_drum.c in the 4.{1,2,3,3-tahoe,3-reno} system:) /* * Expand or contract the virtual swap segment mapped * by the argument diskmap so as to just allow the given size. * * FOR NOW CANT RELEASE UNLESS SHRINKING TO ZERO, SINCE PAGEOUTS MAY * BE IN PROGRESS... TYPICALLY NEVER SHRINK ANYWAYS, SO DOESNT MATTER MUCH */ vsexpand(vssize, dmp, canshrink) register segsz_t vssize; register struct dmap *dmp; { ... -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 405 2750) Domain: chris@cs.umd.edu Path: uunet!mimsy!chris
dvv@hq.demos.su (Dmitry V. Volodin) (10/11/90)
In article <PCG.90Oct10212600@odin.cs.aber.ac.uk> pcg@cs.aber.ac.uk (Piercarlo Grandi) writes: >Now there is a catch: even if your storage reclaimer detectes that a >block of memory just under the break has become free, and lowers the >break as a result, in many UNIX kernels this regrettably will not >release any pages to the kernel mmeory pool -- in some it will not even >invalidate page table entries beyond the break. This is probably because More of that - in some paging evnvironments brk() is a dummy! When the process addresses memory beyond the brk level the kernel just adds another one page to porcess's memory pool. -- Dmitry V. Volodin <dvv@hq.demos.su> | fax: +7 095 233 5016 | Call me Dima (D-'ee-...) phone: +7 095 231 2129 |