On 27 February 2011 11:12, james anderson <james.anderson@...> wrote:
> i have noticed that a long-running sbcl accumulates "unreferenced"
> dynamic objects.
> the immediate symptom is that entries remain in weak-keyed hash
> tables for which the only initial reference was a term in an
> anonymous lambda expression.
Can you provide a test-case which demonstrates exactly that? I'm
afraid the code you sent does not.
> if i try something obvious like
> (loop (let ((x (let ((object (copy-seq "asdf")))
> (setf (literal-language-tag object) "EX")
> (compile nil `(lambda (x)
> ,@(loop for i from 0 below 1000000
> collect (list 'incf 'x))
> (unless (typep x 'function) (return))))
> after a short time, an image looks like
> * (sb-ext:gc)
> * (room)
...this actually isn't obvious at all. What does (SETF LITERAL-LANGUAGE-TAG do?
Also, (sb-ext:gc) usually only runs the nursery collection. To force a
complete collection, you need to do (sb-ext:gc :full t).
Finally, since the loop doesn't terminate, it is completely plausible
that most of the objects on the heap are actually leftovers from the
interrupted compiler run -- not the end-results of the compilation.
Using for example this:
(defun stat-room (info &optional gc)
(gc :full t))
(stat-room "pre" t)
(loop repeat 10
(loop repeat 100
do (compile nil `(lambda (x)
,@(loop for i from 0 below 100
collect (list 'incf 'x))
(stat-room "post" t))
you will see heap usage going up and down, and finally returning to
(exactly or close enough) to what it was before.
> if i compile functions each with a "fingerprinted" constituent form,
> _various_ of the forms are retained:
> * (let ((sym (gensym)))
> (dotimes (x 10) (compile nil `(lambda (x) (equal x '(,sym ,x)))))
> (dotimes (i 3) (sb-ext:gc))
> (let ((found nil))
> (dotimes (x 10)
> (let ((list `(,sym ,x)))
> (sb-vm::map-allocated-objects #'(lambda (object code size)
> (declare (ignore code size))
> (when (and (equal object
> list) (not (eq object list)))
> (push object found)))
These are remnants objects used in the compiler, retained temporarily
due to conservative stack references, as is the following list. (At
least some of the objects you list are easy to identify as parts of
the *SOURCE-PATHS* table.)
That said, there are probably places in the compiler where we could be
more proactive about breaking reference chains to mitigate effects of