# Confusing array garbage collection, how to get valid heap sn

**URL:** <https://www.ruby-forum.com/t/confusing-array-garbage-collection-how-to-get-valid-heap-sn/104833>\
**Category:** Ruby\
**Created:** [May 23, 2007, 2:40am UTC](https://www.ruby-forum.com/t/confusing-array-garbage-collection-how-to-get-valid-heap-sn/104833 "2007-05-23T02:40:50Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![afg](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/ecc23a/32.png) [@afg](https://www.ruby-forum.com/u/afg)\
**Post date:** [May 23, 2007, 2:40am UTC](https://www.ruby-forum.com/t/confusing-array-garbage-collection-how-to-get-valid-heap-sn/104833/1 "2007-05-23T02:40:50Z")

</div>

We are working on tracking down a memory leak, and are hoping to use  
heap snapshotting to find the culprit. Using the neat bleak\_house  
library:

> **[Evan Weaver](https://evan.vc)**
>
> I'm an engineer, founder, and angel investor in software infrastructure, developer tools, social media, ecommerce, and AI.

I have got snapshotting working on my local machine. Note this library  
does not go through ObjectSpaces, but uses a custom ruby build, so its  
much more accurate in showing the true state of the heap. However,  
there seems to be a bit of a problem, this simple script I wrote for  
testing purposes:

# Snapshot here

a = Array.new(1000) { Object.new }  
a = nil  
1.upto(20) { GC.start; ObjectSpace.garbage\_collect; sleep 1; }

# Snapshot here

Shows that the 1000 objects in the array are still on the heap in the  
second snapshot. Now, I realize GC.start makes no guarantees about  
actually removing the objects marked, but it seems that in this case  
they should go away since I am calling it so aggressively over such a  
long period. What is really strange however is that if I all a.clear  
before setting a to nil, the objects _do_ go away upon the first  
GC.start. So, either there is something still holding those references  
in the above case, or the GC is extraordinarily conservative in  
relation to GC.start.

I’ve also tried wrapping this code up into a class, putting the array  
into an instance variable, and I get the same behavior. (This was to  
make sure there are no procs or something at the root scope holding  
these guys.)

In order to effectively track down memory leaks, there needs to be the  
concept of a totally GC’ed heap snapshot. It appears based upon the  
above behavior this is difficult to get. If the above code was under  
test my heap snapshot would show a ‘leak’ of 1000 objects even though  
my code was correctly dereferencing them. Is there something I am  
missing here?

---

<div class="post-metadata">

**Author:** ![afg](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/ecc23a/32.png) [@afg](https://www.ruby-forum.com/u/afg)\
**Post date:** [May 23, 2007, 4:01am UTC](https://www.ruby-forum.com/t/confusing-array-garbage-collection-how-to-get-valid-heap-sn/104833/2 "2007-05-23T04:01:55Z")

</div>

Hi,

In message “Re: Confusing array garbage collection, how to get valid  
heap snapshot?”  
on Wed, 23 May 2007 09:40:04 +0900, Greg F. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
writes:

|Shows that the 1000 objects in the array are still on the heap in the  
|second snapshot. Now, I realize GC.start makes no guarantees about  
|actually removing the objects marked, but it seems that in this case  
|they should go away since I am calling it so aggressively over such a  
|long period. What is really strange however is that if I all a.clear  
|before setting a to nil, the objects _do_ go away upon the first  
|GC.start. So, either there is something still holding those references  
|in the above case, or the GC is extraordinarily conservative in  
|relation to GC.start.

It sometimes happens. I am afraid the array address is pointed from  
somewhere in the machine stack.

```
          matz.

```

---

<div class="post-metadata">

**Author:** ![afg](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/ecc23a/32.png) [@afg](https://www.ruby-forum.com/u/afg)\
**Post date:** [May 23, 2007, 4:55am UTC](https://www.ruby-forum.com/t/confusing-array-garbage-collection-how-to-get-valid-heap-sn/104833/3 "2007-05-23T04:55:59Z")

</div>

On May 22, 7:00 pm, Yukihiro M. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> It sometimes happens. I am afraid the array address is pointed from  
> somewhere in the machine stack.
> 
> ```
> matz.
> 
> ```

Ah. Could I get some pointers in the source to look to better  
understand this dynamic? (How and why this stack is retained  
within ruby after the return of the ruby method?)

-Greg

---

<div class="post-metadata">

**Author:** ![afg](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/ecc23a/32.png) [@afg](https://www.ruby-forum.com/u/afg)\
**Post date:** [May 23, 2007, 5:13am UTC](https://www.ruby-forum.com/t/confusing-array-garbage-collection-how-to-get-valid-heap-sn/104833/4 "2007-05-23T05:13:00Z")

</div>

Hi,

In message “Re: Confusing array garbage collection, how to get valid  
heap snapshot?”  
on Wed, 23 May 2007 11:55:05 +0900, Greg F. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
writes:

|Ah. Could I get some pointers in the source to look to better  
|understand this dynamic? (How and why this stack is retained  
|within ruby after the return of the ruby method?)

gc.c especially in the function garbage\_collect().

```
          matz.

```
