[racket-dev] Testing whether a procedure gets collected

From: Robby Findler (robby at eecs.northwestern.edu)
Date: Sat Dec 1 20:46:40 EST 2012

This prints #f for me.

#lang racket

(define (make-box-thing v)
  (make-weak-box (λ (_) v)))

(define bx (make-box-thing 4))
(collect-garbage)
(weak-box-value bx)

And I guess that non-closure procedures are held onto by the modules
they are inside. This program prints #f for me, and it seems to
confirm that hypothesis.

#lang racket

(define bx
  (parameterize ([current-namespace (make-base-namespace)])
    (eval '(module m racket
             (define bx (make-weak-box (λ (_) 1)))
             (provide bx)))
    (eval '(require 'm))
    (eval 'bx)))

(collect-garbage)
(weak-box-value bx)

Robby

On Sat, Dec 1, 2012 at 7:30 PM, Neil Toronto <neil.toronto at gmail.com> wrote:
> Honestly, because I was too rushed to try them before I had to leave this
> morning. :D However, now that I have the chance, I've found that Typed
> Racket doesn't support them. I can't add support using `required/typed',
> because `Weak-Box' would have to be a polymorphic type.
>
> Also, they don't seem to let go of procedure values. This one's value
> doesn't ever turn to #f no matter how many times I collect garbage:
>
>   (define bx (make-weak-box (λ (_) 0)))
>
> Thinking it might be because that lambda doesn't create a closure, I tried
> this:
>
>   (define (make-box-thing v)
>     (make-weak-box (λ (_) v)))
>
>   (define bx (make-box-thing 4))
>
> But this `bx' doesn't let go of its value, either. I can't help but think
> I'm missing something really stupid, though.
>
> Neil ⊥
>
>
> On 12/01/2012 10:58 AM, Robby Findler wrote:
>>
>> How about using a weak box instead?
>>
>> Robby
>>
>> On Sat, Dec 1, 2012 at 11:45 AM, Neil Toronto <neil.toronto at gmail.com>
>> wrote:
>>>
>>> I'm getting ready to push a change to math/array that fixes a memory
>>> leak.
>>> I've devised a test that I think will determine whether an array's
>>> procedure
>>> gets collected after the array is made strict, but I don't know whether
>>> it
>>> works only by accident. Here it is:
>>>
>>>
>>> (define: collected? : (Boxof Boolean)  (box #f))
>>>
>>> (define arr
>>>    (let ([proc  (λ: ([js : Indexes]) 0)])  ; constant array
>>>      (register-finalizer proc (λ (proc) (set-box! collected? #t)))
>>>      (build-array #() proc)))
>>>
>>> (array-strict! arr)
>>> (collect-garbage)
>>> (sleep 0)  ; give finalizers a chance to run?
>>> (check-true (unbox collected?))
>>>
>>>
>>> This test passes for me now, but will fail if anyone else tries it. What
>>> worries me is that (sleep 0) is apparently required, meaning that
>>> finalizers
>>> aren't run immediately when garbage is collected.
>>>
>>> How can I ensure that the finalizer for `proc' gets run before I test the
>>> value of `collected?'?
>>>
>>> Neil ⊥
>>> _________________________
>>>   Racket Developers list:
>>>   http://lists.racket-lang.org/dev
>
>


Posted on the dev mailing list.