I've thought about this some more, and I guess I don't fully understand it after all. Given a pending-finalizer buffer size of XXX, using the -:fXXX option, simply having more than XXX live finalizers forces a major GC every time a new finalizer is created. None of these finalizers are pending, so why does the pending buffer size come into play? Is this simply a pathological case which cannot be fixed without increasing the pending buffer? Are we constrained by the total number of finalizers irrespective of how many are live or pending invocation?
--- Example: setting -:f3 --- #;1> (define abc '(1 2 3)) #;2> (begin (set-finalizer! abc (lambda (x) (print 'bye))) (void)) #;3> (begin (set-finalizer! abc (lambda (x) (print 'bye))) (void)) #;4> (begin (set-finalizer! abc (lambda (x) (print 'bye))) (void)) #;5> (begin (set-finalizer! abc (lambda (x) (print 'bye))) (void)) #;6> (begin (set-finalizer! abc (lambda (x) (print 'bye))) (void)) [debug] too many finalizers (4), forcing ... #;7> (begin (set-finalizer! abc (lambda (x) (print 'bye))) (void)) [debug] too many finalizers (5), forcing ... #;8> (begin (set-finalizer! abc (lambda (x) (print 'bye))) (void)) [debug] too many finalizers (6), forcing ... #;11> (gc #t) 168456 #;12> (define abc '()) #;13> (gc #t) [debug] running 1 finalizers (6 live, 7 allocated) ... bye [debug] running 1 finalizers (5 live, 7 allocated) ... bye ... [debug] running 1 finalizers (0 live, 7 allocated) ... bye 169284 #;14> On 1/20/06, felix winkelmann <[EMAIL PROTECTED]> wrote: > On 1/18/06, Zbigniew <[EMAIL PROTECTED]> wrote: > Ok. Finalizers work like this: > > There is a list of "live" finalizers, that is finalizers that exist > for currently > live data (internally there is also a list of "allocated" finalizers - > the number > of finalizer-records kept in an internal freelist, we reuse them when > they get unused). When a major GC detects that a non-immediate > finalized data object is not forwarded (copied into the second heap-space > during GC), then it is scheduled for finalization and stored in the > "pending-finalizers" buffer (##sys#pending-finalizers). On the next > interrupt (usually after the major GC), this buffer is traversed and > the finalizer procedure is called for every entry in this buffer. > Now, this buffer has a fixed size, so we can only finalize as many > GC'd objects as fit into the buffer. > If you consider now a tight loop that allocates finalized objects, you > can come into a situation where more finalizers are created than > we can release/invoke (since they don't fit into the pending finalizers > buffer). Thus storage consumption grows even if the actual data > could be freed after GC - here we are not allowed because we > still have to invoke the finalizers. What we do currently is to force > GC if there are too many finalizers to free as many as possible. > > The current solution is to increase the size of the pending-finalizers > buffer, done with the "-:fXXX" runtime option. You can also run your > code with "-:d" to see some information about finalization, or use > `(set-gc-report! ...)' to see much more information. > > A more elegant approach might be to make the pending-buffer > dynamically resizable - well, it's on my every-growing todo list... ;-) > > > cheers, > felix > _______________________________________________ Chicken-users mailing list [email protected] http://lists.nongnu.org/mailman/listinfo/chicken-users
