[vw7.x]Locale needsInputMethod on X11 spoils garbage collection

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

[vw7.x]Locale needsInputMethod on X11 spoils garbage collection

Milan Čermák
Hi all,
some time ago I've made czech locale. Because of ISO Latin2 charset on
Linux, I needed to set Locale>>needsInputMethod: to true. It works just
fine up to now when I discovered that garbage collecting acts a little
strange.

To demonstrate it try following code in workspace:
count := Object instanceCount.
a := Object new.
a inspect
"Close the inspector manually"
a := nil.
ObjectMemory garbageCollect.
Object instanceCount = count

With basic #C locale this code answers "true". But when
#needsInputMethod: is set to "true" the instance (and any other
inspected object) will never be collected.
Inspecting the value is the thing that hangs the object in memory.
However when I change Locale back to #C, the instance gets collected...

Any ideas about the source of this?

--
Ing. Milan Čermák
programátor, analytik

[hidden email]

................................................................
e-FRACTAL, s.r.o. => e-business driven company
nám. Míru 15, Praha 2, http://www.e-fractal.cz
tel: 222 512 000, fax: 222 515 000
................................................................


Reply | Threaded
Open this post in threaded view
|

RE: [vw7.x]Locale needsInputMethod on X11 spoils garbage collection

Steven Kelly
Milan,

It would be great if you could add the Czech locale to the Wiki:
http://www.cincomsmalltalk.com/CincomSmalltalkWiki/VW+Locale+Database
The Wiki is badly out of date by the look of things (last real change is from 2002, since then there have been 18 new versions but all just spam attacks and their removals - so sad). I know several people have asked in the past for a Czech locale, and living without one is a real pain because VW just displays black rectangles for some Czech characters.

As to garbage collection, I often find problems with it since 7.x, with objects hanging around despite having no references. It _looks_ to me like the finalization process stops working: if I open a process monitor, show System processes, debug the finalization process and proceed, the objects that were hanging around unnecessarily after gc seem to disappear. Go figure.

Cheers,
Steve

> -----Original Message-----
> From: Milan Cermák [mailto:[hidden email]]
> Sent: 18 January 2006 17:31
> To: [hidden email]
> Subject: [vw7.x]Locale needsInputMethod on X11 spoils garbage
> collection
>
>
> Hi all,
> some time ago I've made czech locale. Because of ISO Latin2
> charset on
> Linux, I needed to set Locale>>needsInputMethod: to true. It
> works just
> fine up to now when I discovered that garbage collecting acts
> a little
> strange.
>
> To demonstrate it try following code in workspace:
> count := Object instanceCount.
> a := Object new.
> a inspect
> "Close the inspector manually"
> a := nil.
> ObjectMemory garbageCollect.
> Object instanceCount = count
>
> With basic #C locale this code answers "true". But when
> #needsInputMethod: is set to "true" the instance (and any other
> inspected object) will never be collected.
> Inspecting the value is the thing that hangs the object in
> memory. However when I change Locale back to #C, the instance
> gets collected...
>
> Any ideas about the source of this?
>
> --
> Ing. Milan Čermák
> programátor, analytik
>
> [hidden email]
>
> ................................................................
> e-FRACTAL, s.r.o. => e-business driven company
> nám. Míru 15, Praha 2, http://www.e-fractal.cz
> tel: 222 512 000, fax: 222 515 000
> ................................................................
>
>
>

Reply | Threaded
Open this post in threaded view
|

[vw7.x][Patch]Locale needsInputMethod on X11 spoils garbage collection

Milan Čermák
Hi all,
this case is solved. The problem with not collecting inspected objects
(even when GC was manually executed) occured only when my czech locale
was in effect. I realized that this was the only case when
X11InputManager gets used. And finally found an IndentityDictionary
holding all openned windows there (instance variable windowMap in
X11InputManager).
I was curious when the window is removed from that dictionary and found
only one method that do it. The #removeXIC: method does "remove by
value" and is called only when its argument is not nil.
Unfortunately there can be such records in the dictionary and thus these
will never leave the system. The record of such occurs when I open
Trippy inspector on anything.
Attached patch fixes adding to that dictionary so that window is not
added when the associated XIC is nil.

Regards,
Milan Čermák

PS: I wonder why there are two instances of ApplicationWindow for any
single one openned.

PPS: Steve, I'll add my czech locale for sure, but I have to clean it up
a bit first.

--
Ing. Milan Čermák
programátor, analytik

[hidden email]

................................................................
e-FRACTAL, s.r.o. => e-business driven company
nám. Míru 15, Praha 2, http://www.e-fractal.cz
tel: 222 512 000, fax: 222 515 000
................................................................

<?xml version="1.0"?>

<st-source>
<time-stamp>From VisualWorks®, 7.3 of 3. prosinec 2004 on 19. leden 2006 at 11:11:09</time-stamp>


<methods>
<class-id>UI.X11InputManager</class-id> <category>private-viewMap</category>

<body package="CSLocale" selector="setXICForWindow:to:">setXICForWindow: aWindow to: anXIC

        anXIC isNil
                ifTrue: [windowMap removeKey: aWindow ifAbsent: []]
                ifFalse: [windowMap at: aWindow put: anXIC]</body>
</methods>

</st-source>
Reply | Threaded
Open this post in threaded view
|

executor (Re: [vw7.x][Patch]Locale needsInputMethod on X11 spoils garbage collection)

Reinout Heeck-2
Milan Čermák wrote:
> PS: I wonder why there are two instances of ApplicationWindow for any
> single one openned.


Easy: one is the real window, one is it's associated #executor that will
deallocate the OS bits of the window after the real window is GC-ed.

Here is a related message I sent to vw-dev a while ago:

-----------

I have been exploring the UI event system and alternative WindowManager
implementations a bit lately.
I kept tripping over the fact that cleaning dead windows was so much work
because
   Window allGeneralInstances
would show me both 'real' windows and #executor copies.

I implemented #executor on DisplaySurface to now return an instance of
DisplaySurfaceFinalizer which simply remembers the GraphicsHandle and
window
class. When this object is sent #finalize it will ask the window class to
#finalizeHandle: the GraphicsHandle.

The class side implementation of #finalizeHandle: will instantiate an empty
window object of the correct class and in turn ask it to
#finalizeHandle: the
handle. This latter method calls #finalize but also has the added twist
that
it changes the class of this short-lived window instance to Array so
that it
won't show up in the #allGeneralInstances results later.

I hereby donate this for inclusion in the base (though I'm not sure it
makes
the mark in terms of necessity).

See attached changeset, there is a race condition while loading it
regarding
the removal of Window>>executor but this hasn't bitten me yet.


To do:

-- Consider using #basicNew
instead of #new in DisplaySurface class>>finalizeHandle:

-- Remove dead code: The implementations of #actAsExecutor on the
DisplaySurface hierarchy are no longer used.
I find this a nice surprise since I regard this #actAsExecutor
initialization
pattern as superfluous code needing too much attention (and it is ugly ;-).



Reinout
-------





<?xml version="1.0"?>

<st-source>
<!-- Changes in change set DisplaySurfaceFinalizer -->
<time-stamp>From VisualWorks®, Pre-Release 7.4 (feb05.1) of February 7, 2005 on February 13, 2005 at 3:23:53 am</time-stamp>


<class>
<name>DisplaySurfaceFinalizer</name>
<environment>Graphics</environment>
<super>Core.Object</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>handle surfaceClass </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>OS-Window System</category>
<attributes>
<package>OS-Window System</package>
</attributes>
</class>

<comment>
<class-id>Graphics.DisplaySurfaceFinalizer</class-id>
<body>DisplaySurfaceFinalizer acts as the #executor for various DisplaySurface subclasses.
It is introduced so that inspecting all instances of ApplicationWindow shows only real windows and not copies that act as executor.

Instance Variables:
        handle &lt;GraphicsHandle&gt;
        surfaceClass &lt;Class&gt;

</body>
</comment>

<methods>
<class-id>Graphics.DisplaySurfaceFinalizer</class-id> <category>initialize-release</category>

<body package="OS-Window System" selector="handle:surfaceClass:">handle: aGraphicsHandle surfaceClass: aClass
        handle := aGraphicsHandle.
        surfaceClass := aClass</body>
</methods>

<methods>
<class-id>Graphics.DisplaySurfaceFinalizer</class-id> <category>printing</category>

<body package="OS-Window System" selector="printOn:">printOn: aStream
        super printOn: aStream.
        aStream
                nextPut: $(;
                print: surfaceClass;
                space;
                print: (handle ifNotNil: [:h | h key]);
                nextPut: $)</body>
</methods>

<methods>
<class-id>Graphics.DisplaySurfaceFinalizer</class-id> <category>privileged</category>

<body package="OS-Window System" selector="finalize">finalize
        "Release my external storage."

        "I don't forget the handle since HandleRegistry will re-register me in case of an Exception"

        surfaceClass finalizeHandle: handle</body>

<body package="OS-Window System" selector="releaseHandle">releaseHandle
        "sent from handleregistry at system startup"
        handle:=nil</body>
</methods>


<methods>
<class-id>Graphics.DisplaySurface class</class-id> <category>finalization</category>

<body package="OS-Window System" selector="finalizeHandle:">finalizeHandle: aGraphicsHandle
        ^self new finalizeHandle: aGraphicsHandle</body>
</methods>


<methods>
<class-id>Graphics.DisplaySurface</class-id> <category>initialize-release</category>

<body package="OS-Window System" selector="finalizeHandle:">finalizeHandle: aGraphicsHandle
        "I am a short-lived instance only here to release the OS resources of aGraphicsHandle"

        handle := aGraphicsHandle.
        self finalize.
        "Change class to get out of list of
                Window allGeneralInstances"
        self changeClassTo: Array</body>
</methods>

<methods>
<class-id>Graphics.DisplaySurface</class-id> <category>finalization</category>

<body package="OS-Window System" selector="executor">executor
        ^DisplaySurfaceFinalizer new handle: handle surfaceClass: self class</body>
</methods>


<remove-selector>
<class-id>Graphics.Window</class-id> <selector>executor</selector>
</remove-selector>


</st-source>