Re: [racket-dev] Testing whether a procedure gets collected
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 On 01-12-12 18:45, Neil Toronto wrote: Rather than a guarantee (or a probabilistic estimate) of actual collection, could the garbage collector's opinion of what is or isn't garbage be exposed somehow? Marijn -BEGIN PGP SIGNATURE- Version: GnuPG v2.0.19 (GNU/Linux) Comment: Using GnuPG with undefined - http://www.enigmail.net/ iEYEARECAAYFAlDAUtAACgkQp/VmCx0OL2xK+ACfeSZXDxrYv93gfCu2wlqqnMDW AIYAn0D/LZsml0eP2625gE92VzjpiMAv =cEMa -END PGP SIGNATURE- _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] Testing whether a procedure gets collected
Thanks. Is the N suggestion a future-proofing kind of a thing, or is there something today that could cause such a test to pass where a single one might fail? Robby On Mon, Dec 3, 2012 at 10:42 AM, Matthew Flatt wrote: > This guide material (as opposed to language specification and > guarantees) looks pretty good to me. I'll edit and add the suggestion > of N allocations. > > At Mon, 3 Dec 2012 10:39:09 -0600, Robby Findler wrote: >> Let me also say that I think it is important to give advice on how to >> test so I think we need to say something. >> >> Robby >> >> On Mon, Dec 3, 2012 at 10:37 AM, Robby Findler >> wrote: >> > On Mon, Dec 3, 2012 at 7:47 AM, Matthew Flatt wrote: >> >> At Mon, 3 Dec 2012 08:04:15 -0500, Sam Tobin-Hochstadt wrote: >> >>> On Mon, Dec 3, 2012 at 7:54 AM, Robby Findler >> >>> wrote: >> >>> > >> >>> > I agree that when something is collected is a pretty intentional >> >>> > property but I think it is possible to say a little bit more since >> >>> > there is a pretty stable core idea there (namely that if something >> >>> > isn't reachable and you call collect-garbage you can be pretty sure >> >>> > it'll be gone -- this was not the case back in the boehm gc days). >> >>> >> >>> Do we really want to commit to this? I agree that it's true for a >> >>> simple 2-generation GC, but something more complex like the Sun >> >>> garbage-first collector or Felix Klock's regional collector wouldn't >> >>> have this property, let alone something more complex like stack >> >>> allocation for non-escaping data. >> >> >> >> Yes, I think that a guarantee about individual objects with respect to >> >> `collect-garbage' is going to be too strong, because the garbage >> >> collector is meant to provide asymptotic guarantees instead of >> >> individual-object guarantees. >> >> >> >> I think tests like Neil's are best written to allocate N things and >> >> check that a good fraction of the N are released by a garbage >> >> collection. In Neil's specific example, I'd probably write the test to >> >> allocate 100 or 1000 of them, each with its own weak box, and make sure >> >> that at most of the weak boxes are empty after a forced collection. >> > >> > Ah, whoops. I went and wrote a section to try to explain this >> > (assuming the current tech) before reading this message. >> > >> > It is here: >> > >> > >> http://git.racket-lang.org/plt/blob/280d924349c2af595af307d38ffdb24940ede80a:/co >> llects/scribblings/guide/performance.scrbl#l417 >> > >> > My initial reaction to the above (perhaps colored by the fact that I >> > just wrote that section) is to still explain the current state, and to >> > revise this explanation when things improve (and, perhaps, explain in >> > the current version that things might improve in the future). >> > >> > Or maybe does someone else want to try to edit my prose to take this >> > into account? >> > >> > Robby _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] Testing whether a procedure gets collected
This guide material (as opposed to language specification and guarantees) looks pretty good to me. I'll edit and add the suggestion of N allocations. At Mon, 3 Dec 2012 10:39:09 -0600, Robby Findler wrote: > Let me also say that I think it is important to give advice on how to > test so I think we need to say something. > > Robby > > On Mon, Dec 3, 2012 at 10:37 AM, Robby Findler > wrote: > > On Mon, Dec 3, 2012 at 7:47 AM, Matthew Flatt wrote: > >> At Mon, 3 Dec 2012 08:04:15 -0500, Sam Tobin-Hochstadt wrote: > >>> On Mon, Dec 3, 2012 at 7:54 AM, Robby Findler > >>> wrote: > >>> > > >>> > I agree that when something is collected is a pretty intentional > >>> > property but I think it is possible to say a little bit more since > >>> > there is a pretty stable core idea there (namely that if something > >>> > isn't reachable and you call collect-garbage you can be pretty sure > >>> > it'll be gone -- this was not the case back in the boehm gc days). > >>> > >>> Do we really want to commit to this? I agree that it's true for a > >>> simple 2-generation GC, but something more complex like the Sun > >>> garbage-first collector or Felix Klock's regional collector wouldn't > >>> have this property, let alone something more complex like stack > >>> allocation for non-escaping data. > >> > >> Yes, I think that a guarantee about individual objects with respect to > >> `collect-garbage' is going to be too strong, because the garbage > >> collector is meant to provide asymptotic guarantees instead of > >> individual-object guarantees. > >> > >> I think tests like Neil's are best written to allocate N things and > >> check that a good fraction of the N are released by a garbage > >> collection. In Neil's specific example, I'd probably write the test to > >> allocate 100 or 1000 of them, each with its own weak box, and make sure > >> that at most of the weak boxes are empty after a forced collection. > > > > Ah, whoops. I went and wrote a section to try to explain this > > (assuming the current tech) before reading this message. > > > > It is here: > > > > > http://git.racket-lang.org/plt/blob/280d924349c2af595af307d38ffdb24940ede80a:/co > llects/scribblings/guide/performance.scrbl#l417 > > > > My initial reaction to the above (perhaps colored by the fact that I > > just wrote that section) is to still explain the current state, and to > > revise this explanation when things improve (and, perhaps, explain in > > the current version that things might improve in the future). > > > > Or maybe does someone else want to try to edit my prose to take this > > into account? > > > > Robby _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] Testing whether a procedure gets collected
Let me also say that I think it is important to give advice on how to test so I think we need to say something. Robby On Mon, Dec 3, 2012 at 10:37 AM, Robby Findler wrote: > On Mon, Dec 3, 2012 at 7:47 AM, Matthew Flatt wrote: >> At Mon, 3 Dec 2012 08:04:15 -0500, Sam Tobin-Hochstadt wrote: >>> On Mon, Dec 3, 2012 at 7:54 AM, Robby Findler >>> wrote: >>> > >>> > I agree that when something is collected is a pretty intentional >>> > property but I think it is possible to say a little bit more since >>> > there is a pretty stable core idea there (namely that if something >>> > isn't reachable and you call collect-garbage you can be pretty sure >>> > it'll be gone -- this was not the case back in the boehm gc days). >>> >>> Do we really want to commit to this? I agree that it's true for a >>> simple 2-generation GC, but something more complex like the Sun >>> garbage-first collector or Felix Klock's regional collector wouldn't >>> have this property, let alone something more complex like stack >>> allocation for non-escaping data. >> >> Yes, I think that a guarantee about individual objects with respect to >> `collect-garbage' is going to be too strong, because the garbage >> collector is meant to provide asymptotic guarantees instead of >> individual-object guarantees. >> >> I think tests like Neil's are best written to allocate N things and >> check that a good fraction of the N are released by a garbage >> collection. In Neil's specific example, I'd probably write the test to >> allocate 100 or 1000 of them, each with its own weak box, and make sure >> that at most of the weak boxes are empty after a forced collection. > > Ah, whoops. I went and wrote a section to try to explain this > (assuming the current tech) before reading this message. > > It is here: > > http://git.racket-lang.org/plt/blob/280d924349c2af595af307d38ffdb24940ede80a:/collects/scribblings/guide/performance.scrbl#l417 > > My initial reaction to the above (perhaps colored by the fact that I > just wrote that section) is to still explain the current state, and to > revise this explanation when things improve (and, perhaps, explain in > the current version that things might improve in the future). > > Or maybe does someone else want to try to edit my prose to take this > into account? > > Robby _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] Testing whether a procedure gets collected
On Mon, Dec 3, 2012 at 7:47 AM, Matthew Flatt wrote: > At Mon, 3 Dec 2012 08:04:15 -0500, Sam Tobin-Hochstadt wrote: >> On Mon, Dec 3, 2012 at 7:54 AM, Robby Findler >> wrote: >> > >> > I agree that when something is collected is a pretty intentional >> > property but I think it is possible to say a little bit more since >> > there is a pretty stable core idea there (namely that if something >> > isn't reachable and you call collect-garbage you can be pretty sure >> > it'll be gone -- this was not the case back in the boehm gc days). >> >> Do we really want to commit to this? I agree that it's true for a >> simple 2-generation GC, but something more complex like the Sun >> garbage-first collector or Felix Klock's regional collector wouldn't >> have this property, let alone something more complex like stack >> allocation for non-escaping data. > > Yes, I think that a guarantee about individual objects with respect to > `collect-garbage' is going to be too strong, because the garbage > collector is meant to provide asymptotic guarantees instead of > individual-object guarantees. > > I think tests like Neil's are best written to allocate N things and > check that a good fraction of the N are released by a garbage > collection. In Neil's specific example, I'd probably write the test to > allocate 100 or 1000 of them, each with its own weak box, and make sure > that at most of the weak boxes are empty after a forced collection. Ah, whoops. I went and wrote a section to try to explain this (assuming the current tech) before reading this message. It is here: http://git.racket-lang.org/plt/blob/280d924349c2af595af307d38ffdb24940ede80a:/collects/scribblings/guide/performance.scrbl#l417 My initial reaction to the above (perhaps colored by the fact that I just wrote that section) is to still explain the current state, and to revise this explanation when things improve (and, perhaps, explain in the current version that things might improve in the future). Or maybe does someone else want to try to edit my prose to take this into account? Robby _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] Testing whether a procedure gets collected
At Mon, 3 Dec 2012 08:04:15 -0500, Sam Tobin-Hochstadt wrote: > On Mon, Dec 3, 2012 at 7:54 AM, Robby Findler > wrote: > > > > I agree that when something is collected is a pretty intentional > > property but I think it is possible to say a little bit more since > > there is a pretty stable core idea there (namely that if something > > isn't reachable and you call collect-garbage you can be pretty sure > > it'll be gone -- this was not the case back in the boehm gc days). > > Do we really want to commit to this? I agree that it's true for a > simple 2-generation GC, but something more complex like the Sun > garbage-first collector or Felix Klock's regional collector wouldn't > have this property, let alone something more complex like stack > allocation for non-escaping data. Yes, I think that a guarantee about individual objects with respect to `collect-garbage' is going to be too strong, because the garbage collector is meant to provide asymptotic guarantees instead of individual-object guarantees. I think tests like Neil's are best written to allocate N things and check that a good fraction of the N are released by a garbage collection. In Neil's specific example, I'd probably write the test to allocate 100 or 1000 of them, each with its own weak box, and make sure that at most of the weak boxes are empty after a forced collection. _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] Testing whether a procedure gets collected
On Mon, Dec 3, 2012 at 7:54 AM, Robby Findler wrote: > > I agree that when something is collected is a pretty intentional > property but I think it is possible to say a little bit more since > there is a pretty stable core idea there (namely that if something > isn't reachable and you call collect-garbage you can be pretty sure > it'll be gone -- this was not the case back in the boehm gc days). Do we really want to commit to this? I agree that it's true for a simple 2-generation GC, but something more complex like the Sun garbage-first collector or Felix Klock's regional collector wouldn't have this property, let alone something more complex like stack allocation for non-escaping data. -- sam th sa...@ccs.neu.edu _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] Testing whether a procedure gets collected
On Sun, Dec 2, 2012 at 11:40 PM, Neil Toronto wrote: > On 12/02/2012 12:10 PM, Robby Findler wrote: >> >> On Sun, Dec 2, 2012 at 11:43 AM, Matthias Felleisen >> wrote: >>> >>> >>> On Dec 1, 2012, at 9:23 PM, Robby Findler wrote: >>> I think the high-level answer is that you have to understand something about details that aren't currently specified but nevertheless are how things currently work and then make a test that will work when you make those additional assumptions (and then keep it running in drdr so you can tell when the assumptions get broken). >>> >>> >>> >>> Doesn't this suggest deep down that Neil is trying to 'beat' >>> Racket and its implementation with his program? I think the >>> entire discussion (I didn't follow every detail) points to >>> something lacking about the language. -- Matthias >> >> >> I think that Neil wants to formulate a test case that checks that his >> datastructure doesn't leak and is complaining about the lack of >> specification for what "If the garbage collector has proven" (quote >> from the docs) means. > > > I didn't mean to sound complain-y... :p Oh no. "complain" here was not meant to be a negative. Sorry. You "expressed dissatisfaction" and I think it is reasonable to do so. >> My experience with similar testing is that the level of specification >> is actually okay. I can't speak for finalizers (they are more complex) >> but weak boxes seem fine. > > > And that helps a lot, so thanks! > > You're both right, of course. I'm essentially trying to test something that > is unobservable. The fact that I can observe it is an implementation > accident. The specific accident, that a weak box is cleared as soon as > possible, happens to be common and generally expected. > > I don't know whether it's worth it in this case to tighten the > specification. I don't want anyone to spend time on it unless it's actually > worth researching. I don't know that there is a paper to be found, but I agree that an informal description that explains a little more about when one can intuitively expect a weak box to be cleared seems useful. I agree that when something is collected is a pretty intentional property but I think it is possible to say a little bit more since there is a pretty stable core idea there (namely that if something isn't reachable and you call collect-garbage you can be pretty sure it'll be gone -- this was not the case back in the boehm gc days). Hm. I'll think more about this and see if I can improve the docs. Robby _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] Testing whether a procedure gets collected
On 12/02/2012 12:10 PM, Robby Findler wrote: On Sun, Dec 2, 2012 at 11:43 AM, Matthias Felleisen wrote: On Dec 1, 2012, at 9:23 PM, Robby Findler wrote: I think the high-level answer is that you have to understand something about details that aren't currently specified but nevertheless are how things currently work and then make a test that will work when you make those additional assumptions (and then keep it running in drdr so you can tell when the assumptions get broken). Doesn't this suggest deep down that Neil is trying to 'beat' Racket and its implementation with his program? I think the entire discussion (I didn't follow every detail) points to something lacking about the language. -- Matthias I think that Neil wants to formulate a test case that checks that his datastructure doesn't leak and is complaining about the lack of specification for what "If the garbage collector has proven" (quote from the docs) means. I didn't mean to sound complain-y... :p My experience with similar testing is that the level of specification is actually okay. I can't speak for finalizers (they are more complex) but weak boxes seem fine. And that helps a lot, so thanks! You're both right, of course. I'm essentially trying to test something that is unobservable. The fact that I can observe it is an implementation accident. The specific accident, that a weak box is cleared as soon as possible, happens to be common and generally expected. I don't know whether it's worth it in this case to tighten the specification. I don't want anyone to spend time on it unless it's actually worth researching. Neil ⊥ _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] Testing whether a procedure gets collected
On Sun, Dec 2, 2012 at 11:43 AM, Matthias Felleisen wrote: > > On Dec 1, 2012, at 9:23 PM, Robby Findler wrote: > >> I think the high-level answer is that you have to understand something >> about details that aren't currently specified but nevertheless are how >> things currently work and then make a test that will work when you >> make those additional assumptions (and then keep it running in drdr so >> you can tell when the assumptions get broken). > > > Doesn't this suggest deep down that Neil is trying to 'beat' > Racket and its implementation with his program? I think the > entire discussion (I didn't follow every detail) points to > something lacking about the language. -- Matthias I think that Neil wants to formulate a test case that checks that his datastructure doesn't leak and is complaining about the lack of specification for what "If the garbage collector has proven" (quote from the docs) means. My experience with similar testing is that the level of specification is actually okay. I can't speak for finalizers (they are more complex) but weak boxes seem fine. Robby _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] Testing whether a procedure gets collected
On Dec 1, 2012, at 9:23 PM, Robby Findler wrote: > I think the high-level answer is that you have to understand something > about details that aren't currently specified but nevertheless are how > things currently work and then make a test that will work when you > make those additional assumptions (and then keep it running in drdr so > you can tell when the assumptions get broken). Doesn't this suggest deep down that Neil is trying to 'beat' Racket and its implementation with his program? I think the entire discussion (I didn't follow every detail) points to something lacking about the language. -- Matthias _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] Testing whether a procedure gets collected
I think the high-level answer is that you have to understand something about details that aren't currently specified but nevertheless are how things currently work and then make a test that will work when you make those additional assumptions (and then keep it running in drdr so you can tell when the assumptions get broken). In this case, I think that a weak box is going to work well to test the code you described at the beginning of this thread. That is, create the array; use some internal thing to extract the procedure from it. Put it into a weak-box; change the state; collect garbage, check the box. I think that won't fail unless you let that procedure be reachable from a finalizer or you somehow get it promoted to the master area (between places) .. or there is a bug. :) Robby On Sat, Dec 1, 2012 at 8:05 PM, Neil Toronto wrote: > Ah. It prints #f for me when I have debugging info turned on in DrRacket; > otherwise I get #. 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 >> 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 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
Re: [racket-dev] Testing whether a procedure gets collected
On 12/01/2012 07:05 PM, Neil Toronto wrote: Ah. It prints #f for me when I have debugging info turned on in DrRacket; otherwise I get #. 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. [...] Maybe a weak box containing a random closure would work. Hmm... This seems to evaluate to #f under all circumstances: #lang racket (define (make-box-thing v) (make-weak-box (λ (_) v))) (define bx (make-box-thing (random))) (collect-garbage) (weak-box-value bx) I can't think of a way the optimizer could defeat that. It *has* to create a closure... right? Neil ⊥ _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] Testing whether a procedure gets collected
Ah. It prints #f for me when I have debugging info turned on in DrRacket; otherwise I get #. 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 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 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
Re: [racket-dev] Testing whether a procedure gets collected
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 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 >> 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
Re: [racket-dev] Testing whether a procedure gets collected
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 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
Re: [racket-dev] Testing whether a procedure gets collected
How about using a weak box instead? Robby On Sat, Dec 1, 2012 at 11:45 AM, Neil Toronto 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
[racket-dev] Testing whether a procedure gets collected
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