# More precise clause garbage collection

**URL:** <https://swi-prolog.discourse.group/t/more-precise-clause-garbage-collection/1980>\
**Category:** Announce\
**Created:** [March 8, 2020, 11:26am UTC](https://swi-prolog.discourse.group/t/more-precise-clause-garbage-collection/1980 "2020-03-08T11:26:09Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [March 8, 2020, 11:26am UTC](https://swi-prolog.discourse.group/t/more-precise-clause-garbage-collection/1980/1 "2020-03-08T11:26:09Z")

</div>

I pushed some patches that refine clause garbage collection to not only keep track of the oldest goal that still accesses some predicate, but all generations up to some threshold and an interval above this threshold. This way we can remove any erased clause that is not needed for the _logical update semantics_ of some goal. The extreme scenario is below. As the d/1 call blocked all clauses clause GC was completely ineffective (on d/1) in this scenario. In the new implementation clauses added and removed in _keep playing around with d/1_ are subject to clause GC as the d/1 call does not generate these anyway.

```prolog
:- dynamic d/1.

go :-
    assert(d(1)),
    assert(d(2)),
    d(X),
    <keep playing around with d/1)>

```

If you have programs doing a lot of assert/retract with non-deterministic retract and/or access, please give this a try. The expectation is that clause GC is a bit slower, but as it runs on its own thread that shouldn’t matter much, memory use may go down (this was started due to a program that grew to 70Gb, of which 50Gb in erased but not reclaimed clauses which now stays at 1Gb for clause storage). It may also improve performance as there are fewer garbage clauses in dynamic predicates.
