Ah. It prints #f for me when I have debugging info turned on in DrRacket; otherwise I get #<procedure>. Must be inlining keeping it around or something.

The problem with either finalizers or weak boxes is that neither provides enough guarantees. Finalizers are never guaranteed to be run. A weak box may not be the only reference to a procedure value, depending on what optimizations are done. I'm trying to test something that's normally not supposed to be observable.

For now, I've got a finalizer on an array procedure that's created at the beginning of the 1000-line test module, and I test that the finalizer was run at the end. I've also got a (collect-garbage) and a (sleep 0) in there. It works... for now, on my machine.

Maybe a weak box containing a random closure would work. Hmm...

On 12/01/2012 06:46 PM, Robby Findler wrote:
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.toro...@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.toro...@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



_________________________
 Racket Developers list:
 http://lists.racket-lang.org/dev

Reply via email to