Re: [Gc] Is there a way to walk the entire heap of live objects

Christian Schafmeister <[email protected]> Fri, 06 Jun 2014 12:59:01 -0400
Newsgroups gmane.comp.programming.garbage-collection.boehmgc
Message-ID <[email protected]>
Peter,

Thank you for the code below - I incorporated it into reclaim.c and it works perfectly.
I set up the callback to accumulate results in std::maps keyed on the type of each object.

Now I can use this to help me identify my memory problems.

Here is an example of the output that I’m getting:
-------------------- Reachable StringKinds -------------------
strs: total_size:    1136720 count:    26858  avg.sz:       42  largest:     2128 N7gctools17GCString_moveableIcEE
-------------------- Reachable ContainerKinds -------------------
cont: total_size:    2359344 count:        2  avg.sz:  1179672  largest:  1179672 N7gctools17GCVector_moveableIN4core11CacheRecordEEE
cont: total_size:    1287048 count:    14386  avg.sz:       89  largest:    24816 N7gctools17GCVector_moveableINS_9smart_ptrIN4core3T_OEEEEE
cont: total_size:     160944 count:     1339  avg.sz:      120  largest:      288 N7gctools17GCVector_moveableIN4core16RequiredArgumentEEE
cont: total_size:      88920 count:     2632  avg.sz:       33  largest:       88 N7gctools16GCArray_moveableINS_9smart_ptrIN4core3T_OEEELi0EEE
cont: total_size:      51472 count:       73  avg.sz:      705  largest:     3296 N7gctools17GCVector_moveableINS_9smart_ptrIN4core8Symbol_OEEEEE
cont: total_size:      32256 count:      112  avg.sz:      288  largest:      288 N7gctools17GCVector_moveableIN4core16OptionalArgumentEEE
cont: total_size:      15232 count:      272  avg.sz:       56  largest:       56 N7gctools17GCVector_moveableINS_9smart_ptrIN4core6Cons_OEEEEE
cont: total_size:      14784 count:       50  avg.sz:      295  largest:      672 N7gctools17GCVector_moveableIN4core15KeywordArgumentEEE
cont: total_size:       8216 count:        1  avg.sz:     8216  largest:     8216 N7gctools17GCVector_moveableIN4core14DynamicBindingEEE
cont: total_size:       3288 count:        1  avg.sz:     3288  largest:     3288 N7gctools17GCVector_moveableINS_9smart_ptrIN6clbind10ClassRep_OEEEEE
cont: total_size:       1560 count:        1  avg.sz:     1560  largest:     1560 N7gctools17GCVector_moveableINS_9smart_ptrIN4core11Character_OEEEEE
cont: total_size:       1560 count:        1  avg.sz:     1560  largest:     1560 N7gctools17GCVector_moveableINS_9smart_ptrIN4core5Str_OEEEEE
cont: total_size:       1024 count:        1  avg.sz:     1024  largest:     1024 N7gctools17GCVector_moveableIN4core14ExceptionEntryEEE
cont: total_size:        808 count:       13  avg.sz:       62  largest:      136 N7gctools17GCVector_moveableINS_9smart_ptrIN4core9Package_OEEEEE
cont: total_size:        392 count:        7  avg.sz:       56  largest:       56 N7gctools17GCVector_moveableIPN4core15SequenceStepperEEE
cont: total_size:        168 count:        3  avg.sz:       56  largest:       56 N7gctools17GCVector_moveableINS_9smart_ptrIN4core16SourceFileInfo_OEEEEE
cont: total_size:        152 count:        1  avg.sz:      152  largest:      152 N7gctools17GCVector_moveableIN4core11AuxArgumentEEE
-------------------- Reachable LispKinds -------------------
lisp: total_size:    2561936 count:    80050 avg.sz:       32 N4core6Cons_OE
lisp: total_size:     638880 count:    19965 avg.sz:       32 N4core5Str_OE
lisp: total_size:     592560 count:    14814 avg.sz:       40 N4core8Symbol_OE
lisp: total_size:     454960 count:    11374 avg.sz:       40 N4core15VectorObjects_OE
lisp: total_size:     335104 count:    10472 avg.sz:       32 N4core8Bignum_OE
lisp: total_size:     215432 count:     3847 avg.sz:       56 N4core18CompiledFunction_OE
lisp: total_size:     200112 count:     8338 avg.sz:       24 N4core14StandardChar_OE
lisp: total_size:     194272 count:     6071 avg.sz:       32 N4core14CompiledBody_OE
lisp: total_size:     183696 count:     7654 avg.sz:       24 N4core13DoubleFloat_OE
lisp: total_size:     146816 count:     2294 avg.sz:       64 N4core10Instance_OE
lisp: total_size:     137104 count:     1558 avg.sz:       88 N4core19LambdaListHandler_OE
lisp: total_size:     121392 count:     5058 avg.sz:       24 N4core8Fixnum_OE
lisp: total_size:     102408 count:     2560 avg.sz:       40 N4core12ValueFrame_OE
lisp: total_size:      88592 count:     1582 avg.sz:       56 N4core9BuiltIn_OE
lisp: total_size:      79000 count:     2468 avg.sz:       32 N4core15SourcePosInfo_OE
lisp: total_size:      64640 count:     1616 avg.sz:       40 N5llvmo10Function_OE
lisp: total_size:      64360 count:     1609 avg.sz:       40 N4core13HashTableEq_OE
lisp: total_size:      54360 count:     1359 avg.sz:       40 N4core14HashTableEql_OE
lisp: total_size:      37312 count:      583 avg.sz:       64 N4core31SingleDispatchGenericFunction_OE

On Jun 6, 2014, at 12:16 AM, Peter Wang <[email protected]> wrote:

> On Thu, 05 Jun 2014 07:57:53 -0400, Christian Schafmeister <[email protected]> wrote:
>> Hi there,
>> 
>> Is there any functionality in the Boehm GC that would allow me to
>> freeze the garbage collector and walk the heap of live objects?    I’d
>> like to take an inventory of all of the live objects to determine the
>> source of my current memory problems (30 GB of virtual memory used
>> after 4 hours of runtime).
> 
> Hi,
> 
> We do something like that in the Mercury project using the following
> function.
> 
> I am not an expert on Boehm GC internals, and the code is only used in a
> special memory profiling grade, so not heavily exercised.
> Please let me know if there is something wrong with it.
> 
> Peter
> 
> (in reclaim.c)
> 
> STATIC void GC_mercury_do_enumerate_reachable_objects(struct hblk *hbp,
>    word dummy)
> {
>    struct hblkhdr * hhdr = HDR(hbp);
>    size_t sz = hhdr -> hb_sz;
>    size_t bit_no;
>    char *p, *plim;
> 
>    if (GC_block_empty(hhdr)) {
>        return;
>    }
> 
>    p = hbp->hb_body;
>    bit_no = 0;
>    if (sz > MAXOBJBYTES) { /* one big object */
>        plim = p;
>    } else {
>        plim = hbp->hb_body + HBLKSIZE - sz;
>    }
>    /* Go through all words in block. */
>    while (p <= plim) {
>        if (mark_bit_from_hdr(hhdr, bit_no)) {
>            GC_mercury_callback_reachable_object((GC_word *)p,
> 		BYTES_TO_WORDS(sz));
>        }
>        bit_no += MARK_BIT_OFFSET(sz);
>        p += sz;
>    }
> }
> 
> GC_INNER void GC_mercury_enumerate_reachable_objects(void)
> {
>    GC_ASSERT(GC_mercury_callback_reachable_object);
>    GC_apply_to_all_blocks(GC_mercury_do_enumerate_reachable_objects, (word)0);
> }

_______________________________________________
bdwgc mailing list
[email protected]
https://lists.opendylan.org/mailman/listinfo/bdwgc