garbage collection

Bulat Ziganshin bulatz at HotPOP.com
Fri Apr 22 07:58:47 EDT 2005


Hello Duncan,

Thursday, April 21, 2005, 5:36:28 PM, you wrote:

DC> On Thu, 2005-04-21 at 10:57 +0100, Simon Marlow wrote:
>> I mentioned madvise() above: this is a compromise solution which
>> involves telling the kernel that the data in memory is not relevant, but
>> doesn't actually free the memory.  The kernel is free to discard the
>> pages if memory gets tight, without actually swapping them to disk.
>> When the memory is faulted in again, it gets filled with zeros.  This is
>> ideal for copying GC: you madvise() the semispace you just copied from,
>> because it contains junk.
>> 
>> IIRC, madvise() is a BSD-ish interface, but other OSs probably have
>> similar facilities.

DC> Linux and Solaris have this interface (Solaris with possibly different
DC> flags MADV_DONTNEED/MADV_FREE).

DC> And there is also a standardised posix_madvise() (that no-one seems to
DC> support!)

DC> That probably covers it for unixy(linux,solaris,*bsd,darwin) systems.
DC> Don't know about win32.

it seems that madvise() is an ideal solution for systems that support
this

for other OS'es we can use unmap+map. the drawback is that OS wastes
time filling this reallocated memory with zeros (at least that does
VirtualFree+VirtualAlloc under WIN XP), so this will add 5-10% to cost
of major GCs.

as i can see in GC.c, we can't free old memory before allocating all
new one, so in case of physical memory shortage this algorithm will be
worse than compacting?



also while viewing MBlock.c i wonder why you are aligning megablocks
to megabyte boundary - may be 8-byte aligning would be enough?
megablocks are never copied or allocated as whole, and even in this
case aligning to CPU cache line boundary will be enough


another strange thins is what under win32 (and only win32) without
"+RTS -M" option we are restricted to 256 Mbytes of heap. see at this
code:

>   if ( (base_non_committed == 0) || (next_request + size > end_non_committed) ) {
>     if (base_non_committed) {
>         /* Tacky, but if no user-provided -M option is in effect,
>          * set it to the default (==256M) in time for the heap overflow PSA.
>          */
>         if (RtsFlags.GcFlags.maxHeapSize == 0) {
>             RtsFlags.GcFlags.maxHeapSize = size_reserved_pool / BLOCK_SIZE;
>         }
>         heapOverflow();
>     }

i think it must be:

>   if ( (base_non_committed == 0) || (next_request + size > end_non_committed) ) {
>     if (base_non_committed && RtsFlags.GcFlags.maxHeapSize) {
>         heapOverflow();
>     }

in order to allow programs without "+RTS -M" option allocate more than one
256 mbyte chunk

-- 
Best regards,
 Bulat                            mailto:bulatz at HotPOP.com





More information about the Glasgow-haskell-users mailing list