[Openmcl-devel] Garbage collector - ccl:terminate (memory stuff)

Grégory Vanuxem g.vanuxem at gmail.com
Sat Apr 20 05:12:09 PDT 2024


Hello,

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.

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).

2)
The garbage collector reclaims memory in another thread than the
"main" thread? Am I right? It is very difficult from my point of view
to know in real time what it is doing.

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.

Below is a piece of code I am trying to use. I need to inform an
another process via a C wrapper, that it can also release reference(s)
to variable(s) that will, in theory, be released so it can do the
same, in fact I remove myself the reference(s) in that thread/process.
So, I use ccl::terminate as suggested in the Clozure CL documentation,
but practically nothing happens. Is my code wrong? In fact I would
like to fix it.

============ CODE ===========
#+:openmcl
(progn
(defmethod initialize-instance :after ((obj jlref) &rest initargs &key)
    (declare (ignore initargs))
    (ccl:terminate-when-unreachable obj))

(defmethod ccl:terminate ((obj jlref))
    (progn
        (format t "freeing... ~x~%" (jlrefId obj))
        (when (jlrefId obj)
            (format t "freeing... ~x~%" (jlrefId obj))
            (boot::|jl_delete_wrapped_index| (jlrefId obj)))))
)
===============================

Where the class used is very very simple, I am not a regular CL coder,
and even at the base a CL coder.

========= CODE =============
(defclass jlref ()
    ((id  :reader jlrefId   :initarg :id)
    (type :accessor jlrefType :initarg :type))
    (:default-initargs :id nil :type nil))

(defun |make_jlref| (str)
    (let* ((index (write-to-string (random most-positive-fixnum)))
            (id (|jl_setindex_wrap_eval_string| index str)))
        (if (not (equal id "")) ; unless str is a wrong piece of code
            (let ((ret (make-instance 'jlref :id id
                    :type (|jl_string_eval_string|
                        (concatenate 'string
"string(typeof(getindex(refs,\"" id "\")))")))))
                    #+:lispworks (flag-special-free-action index) ; untested
                    #+:cmu (ext:finalize ret (lambda () (free_jlref
index))) ; untested
                    #+:sbcl (sb-ext:finalize ret (lambda ()
                        (sb-concurrency:enqueue index *jqueue*))) ;
use main thread to delete the ref
                    #+:allegro (excl:schedule-finalization ret (lambda
() (free_jlref index))) ret)
            (error "Invalid Julia command"))))

(defun free_jlref (index)
    (|jl_delete_wrapped_index| index))

#+:openmcl
(progn
(defmethod initialize-instance :after ((obj jlref) &rest initargs &key)
    (declare (ignore initargs))
    (ccl:terminate-when-unreachable obj))

(defmethod ccl:terminate ((obj jlref))
    (progn
        (format t "freeing... ~x~%" (jlrefId obj))
        (when (jlrefId obj)
            (format t "freeing... ~x~%" (jlrefId obj))
            (boot::|jl_delete_wrapped_index| (jlrefId obj)))))
)
====================================

More questions later I think.

Best regards,

- Greg


More information about the Openmcl-devel mailing list