On 8/8/2020 9:45 AM, Matthew Flatt wrote:
At Sat, 8 Aug 2020 03:32:57 -0400, George Neuner wrote:
> > On 8/8/2020 1:55 AM, Sorawee Porncharoenwase wrote: > > I even saw people doing `collect-garbage` three times, just to be safe > > I guess. And yet theoretically it's not guaranteed that things will be > > claimed back properly.
> >
> > Honestly, there should be a function that does this `collect-garbage` > > until fixpoint or something, so that we don't need to perform this ... > > uh .... ritual. > > There may be no documented guarantee, but I *think* the implementation > assures that 2 collections, back-to-back, are sufficient to reclaim all > objects that were garbage at the beginning of the 1st collection.  At > least for BC Racket.

In the absence of finalization, then a single `collect-garbage` would
always be sufficient, and a second `collect-garage` would have no
effect.

For the specific benchmark in this thread as run in plain `racket`, I
think a single `collect-garbage` is sufficient, and that's what I
normally do.

But finalization complicates the picture --- especially finalization
via `register-finalizer`, since the finalizers run in a background
thread. Because of that background thread, in a context that uses a
library like `racket/gui`, I sometimes use repetitions of

  (collect-garbage)
  (sync (system-idle-evt))

Yes.  But, at least if you use the generational collector, you know that once an object has been finalized it will be collected the next time the GC looks at it:  i.e. at or before the next major collection.

But there is the issue of incremental GC.  Incremental complicates the notion of the GC "cycle" because it interleaves GC with execution of the mutator and splits a single "full" collection into many partial collections.  I don't know enough about Racket's implementation to say whether objects that become garbage *during* a GC cycle can be collected in that same cycle, or whether they must wait for the next.


But in truth these details should not matter much except for debugging, benchmarking, or for programs that must operate in limited memory.


It's difficult to know whether the libraries that you use rely on
finalization. Also, finalization means that there is no simple number
of `(collect-garbage)`s and `(sync (system-idle-evt))`s that are needed
to really collect everything that could potentially be collected;
finalization chains can require an arbitrary number of
`(collect-garbage)` cycles to clean up (so libraries should avoid
finalization chains!). The collector is precise and the compiler is
safe-for-space, so you can reason about the reachability of an
individual value, but reasoning precisely about overall memory use
across many libraries is difficult or impossible.

Using an extra `(collect-garbage)` is not ideal and often not
necessary, but it's a reasonable just-to-be-sure habit.


Matthew

George

--
You received this message because you are subscribed to the Google Groups "Racket 
Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/9cb6e5ef-c3f3-2fdd-44a9-88f9e0c9036b%40comcast.net.

Reply via email to