On 24.06.2014, at 15:30, Max Leske <maxle...@gmail.com> wrote:

> For documentation purposes, this is what I found to be necessary to really 
> clean all window instances. Note that this only works reliably when invoked 
> from a non-UI process (e.g. via WAKom).
> 
> 
> cleanupWindows
>       "in general: the gabage collector seems to be unable to resolve all 
> circular dependencies with weak pointers.
>       This forces us to explicitly remove the weak pointers to enable garbage 
> colltection.
>       It also seems to be a problem to invoke the cleanup from within a UI 
> process (e.g. from a workspace). 
>       Ergo: 
>               - when invoked from a workspace not all instances may be 
> garbage collected
>               - when invoked from a non UI process (e.g. WAKom) all instances 
> should have been collected
>               - performning a manual garbage collection after having invoked 
> this code from a workspace will
>                       (usually) remove the pending instances (new process 
> context)"
>       | count |
>       count := 1.
>       self
>               cleanupEvents;

I forgot: #cleanupEvents is simply “EventManager cleanUp: true”

>               cleanupWorkspaces;
>               cleanupSystemWindows.
>       [ Smalltalk garbageCollect. count := count + 1 ] doWhileFalse: [
>               SystemWindow allSubInstances isEmpty or: [ count > 5 "arbitrary 
> number" ] ]
> 
> cleanupWorkspaces
>       PluggableTextMorph allSubInstances do: [ :each | each  
>               hasUnacceptedEdits: false;
>               askBeforeDiscardingEdits: false;
>               myDependents: nil ]
> 
> cleanupSystemWindows
>       [ [ SystemWindow allSubInstances do: [ :window |
>               window 
>                       makeClosable;
>                       delete ] ] 
>                               on: Error 
>                               do: [ :ex | 
>                                       "may get here because we're trying to 
> delete a window which has been deleted already."
>                                       ex return  ].
>       Smalltalk garbageCollect.
>       "already deleted but still hanging aroung (also see #cleanupEvents and 
> #cleanupWorkspaces)"
>       SystemWindow allSubInstances 
>               select: [ :e | e model isNil and: [ e owner isNil ] ]
>               thenDo: [ :e |
>                       "clean some known places where references can prevent 
> GC"
>                       UITheme current focusIndicator: nil.
>                       ActiveHand mouseOverHandler initialize.
>                       ActiveHand keyboardFocus: nil.
>                       World cleanseStepList.
>                       "e.g. Workspace has a dependents array wich can point 
> to the window"
>                        (PointerFinder pointersTo: e) do: [ :p | 
>                               p class = DependentsArray ifTrue: [
>                                       "the first pointer is the 'main' 
> pointer in about 99% of the cases"
>                                       (PointerFinder pointersTo: p) first 
> removeDependent: e ] ] ] 
>       ] on: Error do: [ "ignore” ]
> 
> 
> On 21.06.2014, at 23:11, Max Leske <maxle...@gmail.com> wrote:
> 
>> Found the problem, documenting it here in case anybody else ever needs this 
>> (remember, this is 1.1.1).
>> 
>> Open a debugger (e.g. by evaluating 1/0), then click into the lower right 
>> workspace and type something. OCompletion will now have added an entry to 
>> the EventManager actionMap with a ContextVariablesInspector instance as the 
>> key. There seems to be a cycle there that can’t be resolved by the garbage 
>> collector, since I wasn’t able to find any non weak global pointers (an 
>> OContext is referenced by an MessageSend in the action map. The OContext 
>> references a morph which is connected to the SystemWindow. Some of those 
>> morphs reference the ContextVariablesInspector as their model).
>> Anyhow, it should be safe to send EventManager>>cleanUp: with argument true 
>> (actionMaps and their contents get recreated on demand), which will release 
>> those entries and allow the garbage collector to collect the SystemWindows, 
>> other morphs and the Debugger instances.
>> 
>> Note that this is probably not an issue in later versions (e.g. 3.0 doesn’t 
>> include EventManager anymore) but it might be relevant for later 1.x 
>> versions.
>> 
>> Max
>> 
>> 
>> On 21.06.2014, at 20:44, Max Leske <maxle...@gmail.com> wrote:
>> 
>>> 
>>> On 21.06.2014, at 18:53, Marcus Denker <marcus.den...@inria.fr> wrote:
>>> 
>>>> 
>>>> On 21 Jun 2014, at 17:36, kilon alios <kilon.al...@gmail.com> wrote:
>>>> 
>>>>> First off:
>>>>> <rant>why do we have an IRC channel if nobody seems to be 
>>>>> listening??</rant>
>>>>> 
>>>>> too small community for an irc channel. My experience with irc is that 
>>>>> 90-99% of people logged in at least are idle. For its size #pharo is 
>>>>> quite active actually.  
>>>>> 
>>>> 
>>>> I am IRC when at work (and not forgetting to start the IRC client). But 
>>>> often when people ask questions it is exactly the wrong moment in time.
>>>> I just *can’t*  instantly drop what I am doing an tend to the IRC channel… 
>>>> I really wonder how people do it… do they really stop their work right in 
>>>> the
>>>> miiddle to answer questions? How are they productive? 
>>> 
>>> I fully agree. I was just momentarily pissed off :)
>>> 
>>>> 
>>>>    Marcus
>>>> 
>>> 
>> 
> 

Reply via email to