From: ··········@gmail.com
Subject: delete-package and GC.
Date: 
Message-ID: <1178138304.973965.227700@o5g2000hsb.googlegroups.com>
Hi folks,

Suppose I execute:

(defpackage :test
 (:use :common-lisp))

(in-package :test)
(defparameter *param* (make-array 20000000))

(in-package :cl-user)
(delete-package :test)

Then even after garbage collection (gc :full t), etc, the huge array
that was allocated remains (as seen via sb-vm:memory-usage).  The */**/
*** variables are also not the issue.

On the other hand, if I (makunbound test::*param*) then the memory
gets freed.  Shouldn't delete-package automatically makunbound all the
symbols that are native to the package?  According to my understanding
of the semantics, if not the mechanics of delete-package, that's what
should happen.

So, if I want to delete a package and cause everything inside of it,
that's not pointed to by other objects, to be GCed, what should I do?
I have some code involving do-symbols to makunbound/fmakunbound, which
goes what I want, but it feels like delete-package should do it
already.

BTW, I'm using SBCL.

From: Juho Snellman
Subject: Re: delete-package and GC.
Date: 
Message-ID: <slrnf3hva0.gou.jsnell@sbz-30.cs.Helsinki.FI>
··········@gmail.com <··········@gmail.com> wrote:
> (in-package :test)
> (defparameter *param* (make-array 20000000))
>
> (in-package :cl-user)
> (delete-package :test)

SBCL will still internally retain references to *PARAM*, for example
to record it as having been proclaimed as a special variable. That
these internal references can prevent *PARAM* from being GCd even once
it's otherwise unreachable is obviously not optimal, and will
hopefully be changed at some point.

> On the other hand, if I (makunbound test::*param*) then the memory
> gets freed.  Shouldn't delete-package automatically makunbound all the
> symbols that are native to the package?  According to my understanding
> of the semantics, if not the mechanics of delete-package, that's what
> should happen.

Not quite. It just means that the symbol can't be reached through the
package object any more. But if there are external references to the
symbols, those symbols must still retain their symbol-value, and we
thus can't makunbound them. So the following code must print 1:

  (defpackage foo)
  (defparameter *foo* 'foo::foo)
  (setf (symbol-value *foo*) 1)
  (delete-package 'foo)
  (print (symbol-value *foo*))

-- 
Juho Snellman
From: Tim Bradshaw
Subject: Re: delete-package and GC.
Date: 
Message-ID: <1178189187.561840.186850@n59g2000hsh.googlegroups.com>
On May 2, 9:38 pm, ··········@gmail.com wrote:

> On the other hand, if I (makunbound test::*param*) then the memory
> gets freed.  Shouldn't delete-package automatically makunbound all the
> symbols that are native to the package?  According to my understanding
> of the semantics, if not the mechanics of delete-package, that's what
> should happen.

No, and in fact something quite different is specified.  From the
spec:

After this operation completes, the home package of any symbol whose
home package had previously been package is implementation-dependent.
Except for this, symbols accessible in package are not modified in any
other way; symbols whose home package is not package remain unchanged.

I think that's actually a bit cautious. For instance it looks to me
like it would be legal for an implementation to intern all the symbols
in a different package, when almost certainly the expectation of users
is that they would become uninterned.  However there are cases where
it would perhaps make sense for an implementation to do that: for
instance if a symbol in the deleted package had been imported into
another package that is probably the only sane thing to do (and then
if it had been imported into *several* other packages which one should
be chosen?).

>
> So, if I want to delete a package and cause everything inside of it,
> that's not pointed to by other objects, to be GCed, what should I do?
> I have some code involving do-symbols to makunbound/fmakunbound, which
> goes what I want, but it feels like delete-package should do it
> already.
>

Your best bet is probably to loop over all symbols, doing *unbound on
them, then uninterning them (from the appropriate package) and then
delete the package.  However it's important to note that you can never
portably rely on GC to clean up anything for you: that's not what it's
for.

--tim