2. User Interface (hah!)
Run CircularGarbageTraceAndSweepImpl. From the Interpreter (not the CommandTool for some obscure reason!), start up the garbage finder. CircularGarbageTraceAndSweep interface has five interesting procedures:
Call with nObjects as the number of objects you want to worry about. Ropes will not be returned in the list if reportRopes is FALSE (but they are counted). ``nGarbage'' is the number of objects seen that are garbage. ``nSeen'' is how many total objects are in the system. Examples ( what you type in bold) :
&1 ← CircularGarbageTraceAndSweepImpl.FindCircularGarbage[10]
=> [nGarbage: 333, nSeen: 35087, garbage: LIST[" 9 Aug 85 HARTMA... Report Requests", "HARTMANN.PA $ 24#117@ 9 Aug 85 10:12:43 PDT", ^[msg: "donahue.pa $ 3#235@12 Aug 85 12:51:50 PDT", tocName: "\t12 Aug 85 donahue.pa A Walnut bulletin b...", startOfSubject: 29, hasBeenRead: TRUE], ^[streamProcs: 2361562B^, streamData: NIL, propList: NIL, backingStream: 7047046B^], "summonerserveron", ^[getChar: IOCommonImpl.DefaultGetChar, endOf: IOCommonImpl.DefaultEndOf, charsAvail: IOCommonImpl.DefaultCharsAvail, getBlock: IOCommonImpl.GetBlockViaGetChar, unsafeGetBlock: IOCommonImpl.UnsafeGetBlockViaGetChar, backup: IOCommonImpl.DefaultBackup, putChar: IOCommonImpl.DefaultPutChar, putBlock: IOCommonImpl.PutBlockViaPutChar, unsafePutBlock: IOCommonImpl.UnsafePutBlockViaPutChar, flush: IOCommonImpl.DefaultFlush, reset: IOCommonImpl.DefaultReset, close: IOCommonImpl.ClosedClose, getIndex: IOCommonImpl.DefaultGetIndex, setIndex: IOCommonImpl.DefaultSetIndex, propList: NIL, variety: input, class: $EditedViewer], ^[getChar: IOCommonImpl.DefaultGetChar, endOf: IOCommonImpl.DefaultEndOf, charsAvail: IOCommonImpl.DefaultCharsAvail, getBlock: IOCommonImpl.GetBlockViaGetChar, unsafeGetBlock: IOCommonImpl.UnsafeGetBlockViaGetChar, backup: IOCommonImpl.DefaultBackup, putChar: IOCommonImpl.DefaultPutChar, putBlock: IOCommonImpl.PutBlockViaPutChar, unsafePutBlock: IOCommonImpl.UnsafePutBlockViaPutChar, flush: IOCommonImpl.DefaultFlush, reset: IOCommonImpl.DefaultReset, close: IOCommonImpl.ClosedClose, getIndex: IOCommonImpl.DefaultGetIndex, setIndex: IOCommonImpl.DefaultSetIndex, propList: NIL, variety: output, class: $ViewersOutput], ^[proc: WalnutMsgSetDisplayerImpl.MsgSetSelectionProc, clientData: 2155302B^, q: 4760662B^], ^[proc: WalnutMsgSetDisplayerImpl.MsgSetSelectionProc, clientData: 2155002B^, q: 4760662B^], ^[proc: NIL, clientData: NIL, q: 4760662B^]]]
&2 ← &1.garbage.rest.rest.first
=> ^[msg: "donahue.pa $ 3#235@12 Aug 85 12:51:50 PDT", tocName: "\t12 Aug 85 donahue.pa A Walnut bulletin board service", startOfSubject: 29, hasBeenRead: TRUE]
&3 ← CircularGarbageTraceAndSweepImpl.WhoPointsToRef[&1.garbage.rest.rest.first, 2]
=> [referers: LIST[^[next: 12434322B^, prev: 2147702B^, iButton: 12160370B^, hbrButton: NIL, tocButton: 12160406B^, container: 10475232B^, msgInfo: 1702212B^], ^1702212B^, ^[ref: 1702212B^, cycleLimit: 2], ^1702212B^, ^[ref: 1702212B^, cycleLimit: 2], LIST[^[msg: "donahue.pa $ 3#235@12 Aug 85 12:51:50 PDT", tocName: "\t12 Aug 85 donahue.pa A Walnut bulletin b...", startOfSubject: 29, hasBeenRead: TRUE], ^[streamProcs: 2361562B^, streamData: NIL, propList: NIL, backingStream: 7047046B^], "summonerserveron", ^[getChar: IOCommonImpl.DefaultGetChar, endOf: IOCommonImpl.DefaultEndOf, charsAvail: IOCommonImpl.DefaultCharsAvail, getBlock: IOCommonImpl.GetBlockViaGetChar, unsafeGetBlock: IOCommonImpl.UnsafeGetBlockViaGetChar, backup: IOCommonImpl.DefaultBackup, putChar: IOCommonImpl.DefaultPutChar, putBlock: IOCommonImpl.PutBlockViaPutChar, unsafePutBlock: IOCommonImpl.UnsafePutBlockViaPutChar, flush: IOCommonImpl.DefaultFlush, reset: IOCommonImpl.DefaultReset, close: IOCommonImpl.ClosedClose, getIndex: IOCommonImpl.DefaultGetIndex, setIndex: IOCommonImpl.DefaultSetIndex, propList: NIL, variety: input, class: $EditedViewer], ^[getChar: IOCommonImpl.DefaultGetChar, endOf: IOCommonImpl.DefaultEndOf, charsAvail: IOCommonImpl.DefaultCharsAvail, getBlock: IOCommonImpl.GetBlockViaGetChar, unsafeGetBlock: IOCommonImpl.UnsafeGetBlockViaGetChar, backup: IOCommonImpl.DefaultBackup, putChar: IOCommonImpl.DefaultPutChar, putBlock: IOCommonImpl.PutBlockViaPutChar, unsafePutBlock: IOCommonImpl.UnsafePutBlockViaPutChar, flush: IOCommonImpl.DefaultFlush, reset: IOCommonImpl.DefaultReset, close: IOCommonImpl.ClosedClose, getIndex: IOCommonImpl.DefaultGetIndex, setIndex: IOCommonImpl.DefaultSetIndex, propList: NIL, variety: output, class: $ViewersOutput], ^[proc: WalnutMsgSetDisplayerImpl.MsgSetSelectionProc, clientData: 2155302B^, q: 4760662B^], ^[proc: WalnutMsgSetDisplayerImpl.MsgSetSelectionProc, clientData: 2155002B^, q: 4760662B^], ^[proc: NIL, clientData: NIL, q: 4760662B^]], ^[ref: 1702212B^, cycleLimit: 2]], gfh: NIL, foundInLocalFrame: TRUE, foundInCircularStructure: FALSE, cycles: 1]
&4 ← CircularGarbageTraceAndSweepImpl.FindCircularGarbageTypes[30, FALSE]
=> [nGarbage: 2116, nSeen: 41644, garbage: LIST[[709], [709], [709], [709], [709], [709], [709], [709], [709], [709], [709], [709], [709], [709], [709], [709], [1507], [1507], [1507], [1507], [550], [1507], [789], [1507], [1507], [1507], [1507], [1507], [1507], [1507]]]
&5 ← PrintTV.PrintType[SafeStorage.GetReferentType[&1.garbage.rest.rest.first], &H.tsOutStream]
WalnutMsgSetDisplayerPrivate.MsgInfoRec
&6 ← PrintTV.PrintType[[709], &H.tsOutStream]
MBQueuePrivate.MyClickInfoObj
&7 ← CircularGarbageTraceAndSweepImpl.FindCircularGarbage[6, FALSE]
=> [nGarbage: 3663, nSeen: 43116, garbage: LIST[^[proc: WalnutMsgSetButtonsImpl.SelectMsgSetProc, clientData: 12161202B^, q: 4760662B^], ^[proc: WalnutMsgSetButtonsImpl.SelectMsgSetProc, clientData: 7120362B^, q: 4760662B^], ^[proc: WalnutMsgSetButtonsImpl.SelectMsgSetProc, clientData: 3142222B^, q: 4760662B^], ^[proc: WalnutMsgSetButtonsImpl.SelectMsgSetProc, clientData: 12161002B^, q: 4760662B^], ^[proc: WalnutMsgSetButtonsImpl.SelectMsgSetProc, clientData: 12161022B^, q: 4760662B^], ^[proc: WalnutMsgSetButtonsImpl.SelectMsgSetProc, clientData: 12161122B^, q: 4760662B^]]]
&8 ← CircularGarbageTraceAndSweepImpl.FindConnectedComponent[&7.garbage.first, 10]
=> [allOnList: FALSE, countReturned: 10, circularObjects: LIST[^[proc: WalnutMsgSetButtonsImpl.SelectMsgSetProc, clientData: 12161202B^, q: 4760662B^], ^[msgSet: [...], spaceButton: 12157576B^, button: 12157614B^, msViewer: NIL, next: 12161222B^, selected: NIL], ^[LOCK: [...], firstEvent: NIL, pushModel: FALSE, newEvent: [...], notifierRunning: FALSE], ^[startLoc: [...], endLoc: [...], proc: NIL, clientData: NIL, fork: TRUE], ^[startLoc: [...], endLoc: [...], proc: MBQueueImpl.UserClick, clientData: 2146052B^, fork: TRUE], NIL, ^[msgSet: [...], spaceButton: 12157632B^, button: 12157650B^, msViewer: NIL, next: 12161242B^, selected: NIL], ^[startLoc: [...], endLoc: [...], proc: NIL, clientData: NIL, fork: TRUE], ^[startLoc: [...], endLoc: [...], proc: MBQueueImpl.UserClick, clientData: 12134442B^, fork: TRUE], ^[msgSet: [...], spaceButton: 12157704B^, button: 12157722B^, msViewer: NIL, next: 12161322B^, selected: NIL]]]
&9 ← &8.circularObjects.first.clientData
=> ^[msgSet: [name: "VM", version: -1], spaceButton: 12157576B^, button: 12157614B^, msViewer: NIL, next: 12161222B^, selected: NIL]
&10 ←
You can now paw around in the circular structure and try to figure out why is isn't collected.
CircularGarbageTraceAndSweep is an interface that allows for this all to be called from a program to automate some sifting.
You might consider first doing a trace and sweep, running the program that you what to measure, then finding the garbage. This avoids the garbage left around by other parts of the system.