Re: Garbage collector - ccl:terminate (memory stuff)

Ron Garret <[email protected]> Sat, 20 Apr 2024 10:55:53 -0700
Newsgroups gmane.lisp.openmcl.devel
Message-ID <[email protected]>
> On Apr 20, 2024, at 5:12 AM, Gr=C3=A9gory Vanuxem =
<[email protected]> wrote:
>=20
> Hello,
>=20
> I have long-standing issues with Clozure CL and its garbage collector
> (GC). A few questions to ask if you can give me some hints about them.
>=20
> 1)
> Is it possible to force a garbage collection in a simple manner? I do
> not want to use this regularly, I just want to temporarily check its
> work. That is I need to know when and if it really garbage collects
> unreferenced personal variables(s).

Call (GC).  Is that simple enough?  :-)

> 2)
> The garbage collector reclaims memory in another thread than the
> "main" thread? Am I right?

Yes.

> It is very difficult from my point of view to know in real time what =
it is doing.

Yes, that's a feature.  The whole point of GC is so you don't have to =
worry about memory management.  The flip side of not worrying is not =
knowing.

> 3)
> I need to know via the Clozure CL GC when memory will be reclaimed,
> more precisely, if a variable is no longer referenced, and will be
> GC-ed, I need to do other stuff on it but I see nothing happening
> apparently. My code, copied/pasted from the documentation, seems not
> effective.

I'm not sure if this was just careless wording or a reflection of a real =
misunderstanding, but the phrase "a variable is no longer referenced" is =
non-sensical.  Variables are not referenced, *objects* are referenced =
*by* variables (and other things).  To be strictly correct, objects are =
referenced by variable *bindings*.  So, for example:

(setf x (list 1 2 3))

The call to LIST creates three objects, all of which are cons cells.  =
All are reachable through the value binding of the symbol X.  If I then =
do:

(setf y (cons 4 x))

I have now created a fourth object, another cons cell.  If I now do:

(setf x nil)

nothing happens with regards to GC because all of the objects I created =
above are still reachable via the value binding of the symbol Y.

If I now do:

(setf y nil)

you would thing that all four of the cons cells I created become =
unreachable, and will be collected the next time GC runs.  However, =
there is a gotcha here: there are three standard variables in CL called =
*, ** and *** which keep track of the three previously returned values =
in the REPL.  So to actually make the four cons cells unreachable I have =
to perform three more interactions in the listener that do not reference =
these three variables, like this:

? (defclass foo () ())
#<STANDARD-CLASS FOO>
? (let ((s *terminal-io*)) (defmethod ccl:terminate ((thing foo)) (print =
'seeya s)))
#<STANDARD-METHOD TERMINATE (FOO)>
? (make-instance 'foo)
#<FOO #x30200277EDFD>
? (ccl:terminate-when-unreachable *)
TERMINATE
? (gc)
NIL
? 1
1
? 2
2
? 3
3
? (gc)
NIL
?=20
SEEYA=20

Note that *standard-output* and *terminal-io* will by default send =
output to the altconsole when ccl:terminate runs.

rg