[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