From: Patrick Jarjoui
Subject: How can i stop the garbage collector from running when i want?
Date: 
Message-ID: <8h2pc1$3j5$1@news.crihan.fr>
Hello,
       Can i stop garbage collector in lisp for a while?, cause is slowing
down my program, i want to run him before or after my
program has ended, if anybody had an experience in it please
tell how to control it?


Thanks


Patrick

From: Martti Halminen
Subject: Re: How can i stop the garbage collector from running when i want?
Date: 
Message-ID: <39350101.C4002F04@solibri.com>
Patrick Jarjoui wrote:

>        Can i stop garbage collector in lisp for a while?, cause is slowing
> down my program, i want to run him before or after my
> program has ended, if anybody had an experience in it please
> tell how to control it?


Garbage collection is not defined in the standard (at all?
Didn't find anything about garbage in a fast look at the
Hyperspec's index).

For anybody to be able to give you a sensible answer, you might
tell us which Lisp implementation you are using. Generally, you
can tweak the GC performance quite a lot, and at least some
implementations allow you to turn it off (until you run out of
memory), but the way to do it is implementation-specific. If you
haven't found the documentation yet, it is likely that there
might be some milder optimization sufficient to reach acceptable
performance rather than just turning it off.

You might also show us your current GC settings and memory
usage, for example the output of

(room t)
and, in case you are running ACL,

(sys:gsgc-parameters)


--
From: Patrick Jarjoui
Subject: Re: How can i stop the garbage collector from running when i want?
Date: 
Message-ID: <8h3aea$8ke$1@news.crihan.fr>
Hello,
       I'm using FRANZ Allegro Common Lisp ver 5.0, i have enough
memory i upgrade it to 524 MB for that purpose, coz i have a simulation
system that i must run it on lisp and every time it runs the garbage
collector

Thanks

Patrick
"Martti Halminen" <···············@solibri.com> a �crit dans le message
news: ·················@solibri.com...
> Patrick Jarjoui wrote:
>
> >        Can i stop garbage collector in lisp for a while?, cause is
slowing
> > down my program, i want to run him before or after my
> > program has ended, if anybody had an experience in it please
> > tell how to control it?
>
>
> Garbage collection is not defined in the standard (at all?
> Didn't find anything about garbage in a fast look at the
> Hyperspec's index).
>
> For anybody to be able to give you a sensible answer, you might
> tell us which Lisp implementation you are using. Generally, you
> can tweak the GC performance quite a lot, and at least some
> implementations allow you to turn it off (until you run out of
> memory), but the way to do it is implementation-specific. If you
> haven't found the documentation yet, it is likely that there
> might be some milder optimization sufficient to reach acceptable
> performance rather than just turning it off.
>
> You might also show us your current GC settings and memory
> usage, for example the output of
>
> (room t)
> and, in case you are running ACL,
>
> (sys:gsgc-parameters)
>
>
> --
From: Martti Halminen
Subject: Re: How can i stop the garbage collector from running when i want?
Date: 
Message-ID: <39354A7B.BD1CA66A@solibri.com>
Patrick Jarjoui wrote:
> 
> Hello,
>        I'm using FRANZ Allegro Common Lisp ver 5.0, i have enough
> memory i upgrade it to 524 MB for that purpose, coz i have a simulation
> system that i must run it on lisp and every time it runs the garbage
> collector

> > Patrick Jarjoui wrote:
> >
> > >        Can i stop garbage collector in lisp for a while?, cause is
> slowing
> > > down my program, i want to run him before or after my
> > > program has ended, if anybody had an experience in it please
> > > tell how to control it?

You might start by reading 
http://www.franz.com/support/documentation/5.0.1/doc/cl/gc.htm

- or wherever you have installed your local copy of it.

That will tell you what the controls are. It won't tell you
which of them to change and in what direction; it depends on
your application.
Finding out what to do requires some work on your part:
1. measure the time your application uses on your problem task.
2. change one setting.
3. measure the time again on the same task
4. change the same setting some more
5. measure again
6. change the setting in the other direction
7. measure
8. change the setting to the best value so far found.
9. change some other setting.
10. measure
repeat until you run out of things to try.


This should produce some changes in your performance; ACL
settings out-of-the-box seem to be meant for smallish
applications. For example excl:*tenured-bytes-limit* seems to be 
5 MB on the trial version; on our application we used to run it
at 300 MB.

For anybody to be able to give you more detailed help would need
more knowledge about your application and settings. How about
catching on your system the output from

excl:*tenured-bytes-limit*

excl:*global-gc-behavior*

(excl:gc :room)

(excl:gc :show)

and posting it here?

--
From: Joe Marshall
Subject: Re: How can i stop the garbage collector from running when i want?
Date: 
Message-ID: <hfber0l4.fsf@alum.mit.edu>
Martti Halminen <···············@solibri.com> writes:

> Finding out what to do requires some work on your part:
> 1. measure the time your application uses on your problem task.
> 2. change one setting.
> 3. measure the time again on the same task
> 4. change the same setting some more
> 5. measure again
> 6. change the setting in the other direction
> 7. measure
> 8. change the setting to the best value so far found.
> 9. change some other setting.
> 10. measure
> repeat until you run out of things to try.

Unfortunately, many of the settings for the ACL garbage collector are
not independent, and the space covered is large.
From: Martti Halminen
Subject: Re: How can i stop the garbage collector from running when i want?
Date: 
Message-ID: <39356E1B.D58AE724@solibri.com>
Joe Marshall wrote:
 
> Martti Halminen <···············@solibri.com> writes:
> > Finding out what to do requires some work on your part:
> > 1. measure the time your application uses on your problem task.
> > 2. change one setting.
> > 3. measure the time again on the same task
> > 4. change the same setting some more
> > 5. measure again
> > 6. change the setting in the other direction
> > 7. measure
> > 8. change the setting to the best value so far found.
> > 9. change some other setting.
> > 10. measure
> > repeat until you run out of things to try.
> 
> Unfortunately, many of the settings for the ACL garbage collector are
> not independent, and the space covered is large.

Yes, I should probably have added an outer loop to this
algorithm to cover more of the combinations :-)

This was intended more as a gentle hint to the original
questioner that there is more to optimizing the GC than just
turning it off...

--
From: Joe Marshall
Subject: Re: How can i stop the garbage collector from running when i want?
Date: 
Message-ID: <u2fer878.fsf@alum.mit.edu>
"Patrick Jarjoui" <···············@insa-rouen.fr> writes:

> Hello,
>        Can i stop garbage collector in lisp for a while?, cause is slowing
> down my program, i want to run him before or after my
> program has ended, if anybody had an experience in it please
> tell how to control it?

The only way to reliably stop the garbage collector is to stop
allocating storage.  If you turn off the garbage collector, you will
run out of memory.  If GC is occuring frequently enough to be a
problem, then you are probably allocating memory at a fairly high rate
and turning off the GC will likely fail rather quickly.

> I'm using FRANZ Allegro Common Lisp ver 5.0, i have enough
> memory i upgrade it to 524 MB for that purpose, coz i have a simulation
> system that i must run it on lisp and every time it runs the garbage
> collector

The default settings of Allegro Common Lisp are probably non-optimal
for your application.  There are a few things you can do to tweak it
to perform much better for certain applications.

First, you should understand that there are two garbage collectors in
Allegro --  the `global' GC and the `generational' GC.  You cannot turn
off the `global' GC, but you can make it run much less frequently.  You
can turn off the `generational' GC, but if it is tuned correctly, it
will reduce the amount of time you spend in the `global' GC.

Turn on the stats and printing:

    (setf (sys:gsgc-switch :print) t)
    (setf (sys:gsgc-switch :verbose) t)
    (setf (sys:gsgc-switch :stats) t)

When the `generational' GC runs, it will print out a line like this: 

    scavenging...done eff: 80%, copy new: 170352 + old: 14552 = 184904

When the `global' GC runs, it will print out like this:

    Mark Pass...done(740+0), marked 362896 objects, max depth = 16, cut 0 xfers.
    Weak-vector Pass...done(10+0).
    Cons-cell swap...done(0+0), 3632 cons cells moved
    Symbol-cell swap...done(10+0), 0 symbol cells moved
    Oldarea break chain...done(80+0), 502 holes totalling 127896 bytes
    Page-compaction data...done(0+0).
    Address adjustment...done(850+0).
    Compacting other objects...done(110+0).
    Page compaction...done(0+0), 0 pages moved.
    New rootset...done(560+0), 82 rootset entries
    Building new pagemap...done(110+0).
    Merging empty oldspace...done, 0 oldspaces merged.
    global gc recovered 157072 bytes of old space.

For most applications, you want to maximize the efficiency of the
`generational' GC, and run the `global' GC as infrequently as
possible, and maximize the amount of space recovered.  Here are some
rules of thumb:

 1. Set the sizes of the `new' and `old' areas (I'm using Franz's
    non-standard terminology here).  Make the `new' area be about 
    a third of the physical memory you are willing to devote to 
    Lisp.  This should allow the `generational' GC to run 
    completely in RAM, and make it run less frequently.

    Set the `old' area to something nice and big.
    (Twice the size of the `new' area if the `new' area is big, even
     larger if your new area is small and your application needs lots of
     memory).

 2. Set EXCL:*TENURED-BYTES-LIMIT* to about the size of the `new'
    area.  This controls how much data can be migrated from the
    `generational' GC to the `global' GC before a `full' garbage
    collection occurs.  This will ensure that a `full' GC happens
    infrequently, and that it is likely to free a fair amount of
    space.  Note:  It will also make `full' GC's much slower.  The
    total impact of a full GC will ultimately be less because you will
    be doing them less frequently.  But you *will* notice your lisp
    drop dead for GC occasionally.

 3. Set the gc-parameter :GENERATION-SPREAD to a low number (like 2).
    This will keep longer lived objects from being copied back and
    forth between the two semi-spaces of the `generational' GC.

When I do this for my application, I find that LISP now makes good use
of a huge amount of RAM, does a `generational' GC about once a minute
where each `generational' GC takes well less than a second.  Each
`generational' GC reclaims 99% of the storage, and only `tenures'
a small fraction (on the order of 1/100th of 1%) of the objects.

`Global' gc's occur a few times an hour at most, and typically take
several seconds, but less than a minute.

There are other GC parameters that you can tweak, but I found that the
behavior of the GC is hard to predict and quite non-linear in the
other parameters.  However, changes to the area sizes, the generation
spread, and the tenured-bytes-limit seem to be much more easy to
understand.

Of course, this won't work for every application (it might not work
for *most* applications, I don't know).  But give it a try and see if
it improves things.

~jrm
From: Barry Margolin
Subject: Re: How can i stop the garbage collector from running when i want?
Date: 
Message-ID: <iscZ4.67$ZK4.1471@burlma1-snr2>
In article <············@alum.mit.edu>,
Joe Marshall  <·········@alum.mit.edu> wrote:
>"Patrick Jarjoui" <···············@insa-rouen.fr> writes:
>
>> Hello,
>>        Can i stop garbage collector in lisp for a while?, cause is slowing
>> down my program, i want to run him before or after my
>> program has ended, if anybody had an experience in it please
>> tell how to control it?
>
>The only way to reliably stop the garbage collector is to stop
>allocating storage.  

I think this response is a bit extreme.  I would be very surprised if most
implementations don't have some kind of WITHOUT-GC macro that you would use
like:

(without-gc
  <forms that should be executed with GC deferred>)

Putting this around sections of the code that are performance critical
should be reasonable.

>		      If you turn off the garbage collector, you will
>run out of memory.  

Only if you turn it off for a long time or are severely limited in virtual
memory.  I recall that on early Lisp Machines the GC was very buggy and
inefficient.  It was common to leave it off, and just reboot the machine
every few days.  Virtual memory was measured in megabytes in those days,
now most operating systems support a gigabyte or more.

-- 
Barry Margolin, ······@genuity.net
Genuity, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
From: Joe Marshall
Subject: Re: How can i stop the garbage collector from running when i want?
Date: 
Message-ID: <ln0qr0uz.fsf@alum.mit.edu>
Barry Margolin <······@genuity.net> writes:

> In article <············@alum.mit.edu>,
> Joe Marshall  <·········@alum.mit.edu> wrote:
> >"Patrick Jarjoui" <···············@insa-rouen.fr> writes:
> >
> >> Hello,
> >>        Can i stop garbage collector in lisp for a while?, cause is slowing
> >> down my program, i want to run him before or after my
> >> program has ended, if anybody had an experience in it please
> >> tell how to control it?
> >
> >The only way to reliably stop the garbage collector is to stop
> >allocating storage.  
> 
> I think this response is a bit extreme.  

It is the limiting case, but it isn't really *that* extreme.  GC's
occur because the program has used up the available memory, if GC is
happening frequently, especially if it is frequent enough to be
annoying, your program has to be consing at a fairly high rate.

> I would be very surprised if most
> implementations don't have some kind of WITHOUT-GC macro that you would use
> like:
> 
> (without-gc
>   <forms that should be executed with GC deferred>)

In many implementations, this won't work.  It depends on how the GC is
implemented.  Many Lisp implementations call the GC from within CONS.
If a memory allocation primitive hits the barrier, it immediately
calls the GC to free up some space before trying again.  On
implementations like this, you simply cannot defer the GC because it
is wired into the allocator.

I believe that Allegro CL does not provide a mechanism for deferring a
`full' GC.

Other systems are more clever:  they reserve a bit of extra room for
consing when doing a GC is not desirable, or they let the memory
allocator grab a new chunk from the OS, or they have a soft barrier
well below the actual memory limit.  These systems might have a form
that defers GC for short periods, but you shouldn't wrap it around
your entire application.

> Putting this around sections of the code that are performance critical
> should be reasonable.
> 
> >		      If you turn off the garbage collector, you will
> >run out of memory.  
> 
> Only if you turn it off for a long time or are severely limited in virtual
> memory.  

`a long time' might not be very long these days.


> I recall that on early Lisp Machines the GC was very buggy and
> inefficient.  It was common to leave it off, and just reboot the machine
> every few days.  Virtual memory was measured in megabytes in those days,
> now most operating systems support a gigabyte or more.

Yes, but remember that the Lisp Machine had a quite a few workarounds
in it.  Most of the system code either made a heroic effort to not
cons, or, if it were a subsystem like the compiler, it would cons in a
special region that could be safely de-allocated at the end of a work
unit. 
From: Duane Rettig
Subject: Re: How can i stop the garbage collector from running when i want?
Date: 
Message-ID: <4em6imv4m.fsf@beta.franz.com>
I am not in the habit of responding to what essentially amounts to
a support issue (if the original poster is supported, he can send
his question to ····@franz.com, even if it is not a bug, per se).

However, I do want to correct a simple mistake in this response:

Joe Marshall <·········@alum.mit.edu> writes:

> First, you should understand that there are two garbage collectors in
> Allegro --  the `global' GC and the `generational' GC.  You cannot turn
> off the `global' GC, but you can make it run much less frequently.  You
> can turn off the `generational' GC, but if it is tuned correctly, it
> will reduce the amount of time you spend in the `global' GC.

It is actually the generational gc that can't be turned off.  You
can easily turn off the global-gc, by setting excl:*global-gc-behavior*
to nil.  In fact, I sometimes advise my customers to do just that
when they see statistics like this:

> When the `global' GC runs, it will print out like this:
> 
>     Mark Pass...done(740+0), marked 362896 objects, max depth = 16, cut 0 xfers.
        [ ... ]
>     global gc recovered 157072 bytes of old space.

Although I don't know what caused this particular global-gc, it
is clear that it is not doing very much at all, and is thus simply
not worth it.  If this is a typical global-gc, then I would
advise turning global-gc off and, if necessary, performing the
global-gc by hand (by typing (gc t) at an opportune time, or
programmatically at a specified time or between major application
usages. etc).

One more point:

> The default settings of Allegro Common Lisp are probably non-optimal
> for your application.  There are a few things you can do to tweak it
> to perform much better for certain applications.

I agree with this; I have never been happy with the default settings
of our global-gc, but have never been able to make it sufficiently
"smart", for the very reason you gave:

> Of course, this won't work for every application (it might not work
> for *most* applications, I don't know).  But give it a try and see if
> it improves things.

The real problem is that there are several models of lisp usage that
we have seen; the current behavior works well for the small model.
It is not possible for us to ship a lisp with global-gc turned off
by default; that would _break_ the many small-to-medium model
applications that we see our customers using.  So we try to advise
our large-model customers, both in documentation, and by problem
report, how to best tune to their particular needs.

Two things that we are doing for our next release to mitigate
the global-gc situation:

 1. The excl:*tenured-bytes-limit* value is now 8 Mb for 32-bit
lisps, and 16 Mb for 64-bit lisps.  This is still a small-model
setting, but since nowadays "small" applications are getting larger
and larger ...

2. There is a new capability to "close" old areas.  Old space
consists of multiple old areas, and some number of the oldest
areas (in fact, all but the newest old area) can be made inviolate
by closing them: global-gc never marks them or compacts them,
no new data are tenured into a closed old area, and all objects
within a closed old area are considered alive.  Thus, only the open
old-areas are compacted, and the global-gc runs much faster.  An
application supplier might load in his app, global-gc everything,
and then close all old areas but one, which his user will use for
tenured data.  When the user is through with a particular usage
of an application, a global-gc will remove garbage quickly, without
touching the application's tenured data.

-- 
Duane Rettig          Franz Inc.            http://www.franz.com/ (www)
1995 University Ave Suite 275  Berkeley, CA 94704
Phone: (510) 548-3600; FAX: (510) 548-8253   ·····@Franz.COM (internet)
From: Joe Marshall
Subject: Re: How can i stop the garbage collector from running when i want?
Date: 
Message-ID: <ln0qpizr.fsf@alum.mit.edu>
Duane Rettig <·····@franz.com> writes:

> Joe Marshall <·········@alum.mit.edu> writes:
> 
> > First, you should understand that there are two garbage collectors in
> > Allegro --  the `global' GC and the `generational' GC.  You cannot turn
> > off the `global' GC, but you can make it run much less frequently.  You
> > can turn off the `generational' GC, but if it is tuned correctly, it
> > will reduce the amount of time you spend in the `global' GC.
> 
> It is actually the generational gc that can't be turned off.  You
> can easily turn off the global-gc, by setting excl:*global-gc-behavior*
> to nil.  

D'oh!  Got 'em backwards.

> 2. There is a new capability to "close" old areas.  Old space
> consists of multiple old areas, and some number of the oldest
> areas (in fact, all but the newest old area) can be made inviolate
> by closing them: global-gc never marks them or compacts them,
> no new data are tenured into a closed old area, and all objects
> within a closed old area are considered alive.  Thus, only the open
> old-areas are compacted, and the global-gc runs much faster.  An
> application supplier might load in his app, global-gc everything,
> and then close all old areas but one, which his user will use for
> tenured data.  When the user is through with a particular usage
> of an application, a global-gc will remove garbage quickly, without
> touching the application's tenured data.

This feature will be much appreciated.