Subject: Re: memory usage in cmucl
From: rpw3@rpw3.org (Rob Warnock)
Date: Fri, 23 Jun 2006 22:10:32 -0500
Newsgroups: comp.lang.lisp
Message-ID: <noudnaGTkY21MAHZnZ2dnUVZ_sqdnZ2d@speakeasy.net>
goose <ruse@webmail.co.za> wrote:
+---------------
| If this happens in any future (compiled) cmucl code where
| should I start looking? Are there any obvious (or non-obvious)
| ways of leaking memory? 
+---------------

1. Don't forget the values of the REPL convenience variables:

      +    *    /   -
      ++   **   //
      +++  ***  ///

   Recently-evaluated forms/values can get "stuck" in there for up
   to four REPL entries [that is, remain visible to the GC], until
   they get pushed off the end of the "shift registers".

2. CMUCL allocates "large" objects separately, and does not always
   release them if you force a GC [with "(GC)"] before the "will
   next occur" limit is hit automatically. Performing a (GC :FULL T)
   should release such things.[1]

Combining these two [watch the "GC completed with" lines!]:

      > (setf *print-length* 25)

      25
      > (gc)
      ; [GC threshold exceeded with 1,044,712 bytes in use.  Commencing GC.]
      ; [GC completed with 1,046,576 bytes retained and -1,864 bytes freed.]
      ; [GC will next occur when at least 13,046,576 bytes are in use.]

      NIL
      > (make-array 1000000)

      #(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ...)
      cmu> (gc :full t)
      ; [GC threshold exceeded with 5,052,792 bytes in use.  Commencing GC.]
      ; [GC completed with 5,042,984 bytes retained and 9,808 bytes freed.]
      ; [GC will next occur when at least 17,042,984 bytes are in use.]

      NIL
      > (gc :full t)
      ; [GC threshold exceeded with 5,046,952 bytes in use.  Commencing GC.]
      ; [GC completed with 5,040,768 bytes retained and 6,184 bytes freed.]
      ; [GC will next occur when at least 17,040,768 bytes are in use.]

      NIL
      > (gc :full t)
      ; [GC threshold exceeded with 5,044,736 bytes in use.  Commencing GC.]
      ; [GC completed with 5,040,784 bytes retained and 3,952 bytes freed.]
      ; [GC will next occur when at least 17,040,784 bytes are in use.]

      NIL
      > (gc :full t)
      ; [GC threshold exceeded with 5,044,752 bytes in use.  Commencing GC.]
      ; [GC completed with 1,040,784 bytes retained and 4,003,968 bytes freed.]
      ; [GC will next occur when at least 13,040,784 bytes are in use.]

      NIL
      > 

By the fourth (GC :FULL T), the array had finally shifted out of
the "***" & "///" variables, and the collection finally succeeded.

[You could have also typed NIL three times and then a single (GC :FULL T),
with the same result.]


-Rob

[1] Actually, in cases like the above, a (GC :GEN 2) will usually do it,
but as long as you're doing it manually, why not use (GC :FULL T)?

-----
Rob Warnock			<rpw3@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607