|Version 1 (modified by wws, 6 years ago)|
The information below describes a feature currently available only in the working-0711 branch in subversion
CCL has a handful of functions that can help find memory leaks.
Finding Lisp Heap Leaks
You can usually tell that you have a lisp heap leak, by comparing the output of room before and after running some suspect code:
(progn (ccl:gc) (ccl:gc) (room))
The two calls to CCL:GC are to make sure that finalization and weak objects are collected.
Once you know you have a leak, comparing two outputs of (CCL:HEAP-UTILIZATION) can sometimes narrow down the possibilities.
(CCL::ALL-OBJECTS-OF-TYPE 'type) returns a list of the objects counted in one line of the (CCL:HEAP-UTILIZATION) output. These tend to be long, so you usually want to avoid printing them, e.g. (DEFPARAMETER *STRINGS* (CCL::ALL-OBJECTS-OF-TYPE 'SIMPLE-BASE-STRING)).
You can use CCL::FAST-SET-DIFFERENCE to compute the difference between two results from CCL::ALL-OBJECTS-OF-TYPE. It's just like the Common Lisp SET-DIFFERENCE function, except it uses a hash table for better speed versus more space.
(CCL::FIND-REFERENCES OBJECT) returns a list of all objects that reference the argument.
(TRANSITIVE-REFERENCERS OBJECT-OR-LIST &OPTIONAL AS-OBJECT) returns a hash table whose keys are objects that transitively reference OBJECT-OR-LIST or, if it's a list and AS-OBJECT is nil, any of its elements.
(CCL::PRINT-REFERENCERS HASH &KEY PREDICATE PAUSE-PERIOD PRINT-CIRCLE PRINT-LENGTH PRINT-LEVEL) prints the hash table returned by TRANSITIVE-REFERENCERS. The key parameters control filtering and printing variables.
Finding C heap leaks
Sometimes memory leaks are due to malloc() calls in the C memory manager, not the lisp heap.
(CCL::MALLINFO) returns the total number of malloc'd bytes. Like room, its output takes a few garbage collectes to stabilize.
Linux has a facility called "mtrace" that lets you save to a file all calls to malloc and free. Then you can parse that file to find memory that was allocated, but not deallocated, along with where in which library the allocation was done. Not as useful as a stack dump for each one, but still often useful.
(CCL::START-MTRACE FILENAME) begins logging, storing the log in FILENAME.
(CCL::STOP-MTRACE) stops logging
(CCL::PARSE-MTRACE-LOG FILENAME) parses the mtrace output, and returns a list of three-element lists, of the form: (Where Size Pointer). Where is the location of unbalanced call to malloc. Size is the size of the allocated pointer. Pointer is the location of the pointer itself. Both START-MTRACE and STOP-MTRACE call CCL:GC once, but you may want to call it and look at the (CCL::MALLINFO) output until the garbage collector has recovered all it can.