Skip to content

Consider adding finalizers to resource heavy objects #34

@nagy

Description

@nagy

I think it might make sense to add finalizers to objects like images. Finalizers allow the garbage-collector to call a function, when an object is no longer referenced. This way, more memory can be automatically freed, for example of images. It could come in useful in situations like the following pseudocode:

(defparameter *level-images* (make-hash-table))
;; prepare level1 
(setf (gethash 1 *level-images*) (load-image "level1-image1.jpg"))
(setf (gethash 2 *level-images*) (load-image "level1-image2.jpg"))
;; load more images of level 1...
;; ... now the player enters level 2
;; all we need to do here is make a new hash table.
(setq *level-images* (make-hash-table))
;; Since the old one is unreferenced, all its contents could be eventually freed.

We do not need to iterate over the content of the container and call #'unload-image. I have had success with the following wrapper.

(defun load-image-gced (filename)
  (let* ((res (load-image filename))
         (cpy (raylib::copy-image res)))
    (sb-ext:finalize res (lambda () (unload-image cpy)))
    res))

Keep in mind, that with the #'copy-image function, the struct is not deeply copied, so it will not use much more memory. Also keep in mind, that this is only additional and you are still free to do some manual memory management where it makes sense. So this would not break existing code. With help from "trivial-garbage" we can write portable code for this.

https://trivial-garbage.common-lisp.dev/

https://www.sbcl.org/manual/#Finalization

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions