Re: Garbage Collection Eligibility and portability



I think the systems you are describing as "aggressive" might
be implemented by having the compiler perform lifetime
analysis on variables, and then conveying that information
to where it can be examined at runtime by the GC. The GC
would be able to tell that certain words on the stack
should not "traced" because they are known to be "dead"
(in the parlance of compiler writers).

I don't know any specific terminology for that.

There isn'tany way to get a given Lisp to act that way.

Usually this would not affect portability. The only
way I can seriously see it affect portability is if
the delay in returning the garbage could cause Lisp to
run out of memory. If this really matters, you could
just put a (setq input-list nil) after the first format
call in secondary.

Matt L wrote:

There seems to be variance in garbage-collected languages, or in options used, that alters exactly when a (strong) variable reference to a memory location ceases holding it from collection.

One type generally follows scope - that is, while code is executing in a scope where the variable is available the referenced memory is ineligible for collection. (Importantly) This tends to include the caller's form for values passed from above.

The other, which I've seen called "Aggressive garbage collection" in some articles on this behavior in C#/.Net (possibly misnamed as it pertains to how the language interacts with the GC, not the GC itself), appears to make a memory location eligible the instant the last reference to the location is used. A caller passing a reference to a function does not keep it ineligible, and the receiving function removes its hold the instance the last reference is made.

I can see the benefits of "aggressive" in composition of code where sizeable intermediate results are passed down into successive phases of a computation.

In my own exploration I have found a case where the distinction between the two, from the point of view of my library and how it should be used, makes a huge difference:

I have tried testing in a couple of lisp variants (CLisp, SBCL and Lispworks); but may lack the expertise to properly test them. I was not able to get SBCL/CLisp to exhibit the "aggressive" behavior.

In Lispworks Win32, the following code exhibits either behavior depending on whether the functions are compiled at a high speed setting/without debug info:


(defun secondary (input-list)
(format t "input-list length is ~A" (length input-list))
(terpri)
(format t "Force collection here")
(terpri)
(force-output)
(break)
(format t "Don't need input-list here")
(force-output))

(defun primary ()
(secondary (make-list 10000000)))


(declaim (optimize (safety 0) (speed 3) (debug 0)))
(compile 'primary)
(compile 'secondary)


In the function "secondary", at the (break) point the code no longer needs that huge memory-hogging list. Cleaning out ram at this point will show how the current environment and settings deal with such references.

Is there a way to make any given lisp exhibit this behavior, surrendering its references the instant it is no longer needed (figure it's inherent to how the implementation uses the stack; but thought I'd ask)? Is there a good way to emulate this behavior without requiring this compiler behavior or characteristic?

I have a library I'd like to publish as portable but this issue may influence its implementation or usage patterns.

Any information on this subject is appreciated. Any good terminology I can search on? Links to discussion of this topic?


.



Relevant Pages

  • Re: novice: mapcan use?
    ... > is symbol in lisp the same as variable in c?)? ... The important point is that a C compiler has a similar structure to ... The reader keeps a reference to the expressions it reads in the ... Some implementations provide a way to invoke the garbage collector. ...
    (comp.lang.lisp)
  • Re: Tsomething(nil).SomeMethod and Tsomething(garbage).SomeMethod should halt the debugger.
    ... > There's no compiler magic to that. ... > reference to ensure it's not nil before calling the destructor. ... simply points Something to the object header. ... > Given an arbitrary memory address, we would need to be able to determine ...
    (alt.comp.lang.borland-delphi)
  • Re: Words on the heap
    ... If you use a target compiler this ... Lisp to have a Common Lisp-style COMPILE function, ... I personally let my system waste memory when compiling. ... one for the JIT. ...
    (comp.lang.forth)
  • Re: question on memory barrier
    ... >> case that a mere sequence point required the compiler to have completed ... Reference: ... Writes to memory may or may not be of that category, ... send the line "unsubscribe linux-kernel" in ...
    (Linux-Kernel)
  • Re: Why does Lisp (SBCL) produce so huge executables?
    ... When Lisp compiles code does it produce a machine code or still keeps ... in C/C++ with lots of libraries would be around 5 to 10 MB. ... space on disk and memory and can it be reduced? ... Of course to the commercial versions of Lisp have a tree shaker that removes unused functions and data and can remove compiler and interpreter if desired. ...
    (comp.lang.lisp)

Loading