Greetings,

First of all, thanks so much for help with this issue.  I would not have been able to use ABCL without the fantastic support I've gotten.  It is really appreciated!

I did a little checking and CL does seem to localize class definitions to packages as it does for regular functions.  Not too surprising.  So, it does make sense for a class definition to be totally eradicated when a package is explicitly deleted.

The serious down side of not eliminating a class definition is that if a package is load, deleted, and reloaded many times, the act of defining the same class (presumably in the same package name but will actually be creating a new package structure) causes (in essence) a memory leak.

Thanks.

Blake McBride




On Thu, Jan 27, 2011 at 1:19 PM, Erik Huelsmann <ehuels@gmail.com> wrote:
To prevent any confusion beforehand: The mail below talks about class
objects, objects which store class definitions, not the actual
instances of those classes, which use those class definitions and
store class-allocated or instance values.

We have fixed a few bugs where memory would be allocated during
(package creation or) FASL loading, but would not be freed upon
package deletion. That was an issue because it's an explicit use-case
for Blake.

Last weekend I came up with another "leak" in ABCL. The word "leak" is
between quotes, because depending on how you look at it, not all of it
may technically be leaky.


My point: it's easy to create a class; simply use a DEFCLASS form.
However, unlike package creation, which can be "undone" through
DELETE-PACKAGE, there's no DELETE-CLASS function to undo the result of
a DEFCLASS.

I started to think about supporting the use-case of deleting a class.
Digging around in our implementation, I found there are several
reasons why a class won't be automatically cleaned up when the package
containing its naming symbol is deleted:

1. Every parent maintains a list of subclasses
   The list contains class objects, meaning that the actual class-object is
   referenced in this list and for that reason can't be GC-ed
2. Every generic function maintains a list of specializing methods
   The methods in the list refer to the dispatch types,
   meaning that the class-objects are strongly referenced from there too
3. Our FIND-CLASS implementation contains strong references to both
   the naming symbols as well as the class-objects.
4. Our implementation uses a cache to speed up the calls to generic
   functions. This cache uses strong references too.


The issue in item (3) can be solved (relatively) easy by developing a
weak hash table which contains both weak keys and values. This hash
table could even be made available as regular Lisp objects.

Item (4) currently uses an explicitly specialized hash table
implemented on the Java side. The hash table could be adapted to use
weak references as well - the effort wouldn't be as generally usable,
but that's just tough luck.


Items (1) and (2) are something to think about though: Is it wise to
implement a function which removes the methods and the class from its
parent? What if the class itself has direct subclasses? Do we signal
an error? Do we provide a parameter forcing the deletion of a whole
tree? Or maybe we should just document how potential users of our CLOS
should proceed if they have the intention to do this, since it won't
be portable anyway?


Myself, I'm currently contemplating "just document" on one hand and
"do whatever we can, even if they're whole trees" on the other...


What do other people think?


Bye,


Erik.

_______________________________________________
armedbear-devel mailing list
armedbear-devel@common-lisp.net
http://common-lisp.net/cgi-bin/mailman/listinfo/armedbear-devel