Hi Stephan,

I filed a issue for this problem, ISSUE#
107157<http://www.openoffice.org/issues/show_bug.cgi?id=107157>
.


Thanks for you help



On Tue, Nov 24, 2009 at 1:29 AM, Stephan Bergmann
<stephan.bergm...@sun.com>wrote:

> Yes, thanks.  I think now I get it.  The code in cleanUp mistakenly thinks
> that Level1Entry.get is backed by a map (where there can be at most one
> entry for a given key) while in fact it is backed by a list (acting like a
> multi-map, allowing multiple entries for a given key).
>
> I will see how best to fix that tomorrow.  If you like, you can file an
> issue (otherwise, I will file one myself).
>
> -Stephan
>
>
> On 11/23/09 18:15, Huaidong Qiu wrote:
>
>> This is a bad list. I print out
>>
>> Type,
>> oid,
>> o.toString()
>>
>> The first one is a unreachable object's weak reference, which causes the
>> growth of list.(not all of them are unreachable, my mistake before)
>>
>> list start +++++++++
>> list size: 6
>> Type[com.sun.star.uno.XCurrentContext]
>> 287d368;msci[0];e64524147b554dde941e6f95d22dc0
>> null
>>
>> Type[com.sun.star.uno.XCurrentContext]
>> 287d368;msci[0];e64524147b554dde941e6f95d22dc0
>>
>> [Proxy:329388962,287d368;msci[0];e64524147b554dde941e6f95d22dc0,Type[com.sun.star.uno.XCurrentContext]]
>>
>> Type[com.sun.star.uno.XCurrentContext]
>> 287d368;msci[0];e64524147b554dde941e6f95d22dc0
>>
>> [Proxy:329388962,287d368;msci[0];e64524147b554dde941e6f95d22dc0,Type[com.sun.star.uno.XCurrentContext]]
>>
>> Type[com.sun.star.uno.XCurrentContext]
>> 287d368;msci[0];e64524147b554dde941e6f95d22dc0
>>
>> [Proxy:329388962,287d368;msci[0];e64524147b554dde941e6f95d22dc0,Type[com.sun.star.uno.XCurrentContext]]
>>
>> Type[com.sun.star.uno.XCurrentContext]
>> 287d368;msci[0];e64524147b554dde941e6f95d22dc0
>>
>> [Proxy:329388962,287d368;msci[0];e64524147b554dde941e6f95d22dc0,Type[com.sun.star.uno.XCurrentContext]]
>>
>> Type[com.sun.star.uno.XCurrentContext]
>> 287d368;msci[0];e64524147b554dde941e6f95d22dc0
>>
>> [Proxy:329388962,287d368;msci[0];e64524147b554dde941e6f95d22dc0,Type[com.sun.star.uno.XCurrentContext]]
>> list end   +++++++++
>>
>>
>> On Mon, Nov 23, 2009 at 9:32 PM, Huaidong Qiu <qiuhuaid...@gmail.com>
>> wrote:
>>
>>  Thanks Stephan,
>>>
>>> I already print out the list's contents, the elements's oid and type are
>>> the same,
>>>  but the objects are unreachable.
>>>
>>> Same oid because those weak references belong to same L1 entry, no
>>> problem
>>> here.
>>>
>>> Let's consider  a Level1Entry contains two Level2Entry: l2_1, l2_2.
>>> if l2_1, l2_2 have same type, l1.get(l2.getType())  will return l2_1
>>> because l1.get will return the first element match the type.
>>>
>>>
>>>            // must only be called while synchronized on map:
>>>            public Level2Entry get(Type type) {
>>>                for (Iterator i = list.iterator(); i.hasNext();) {
>>>                    Level2Entry l2 = (Level2Entry) i.next();
>>>                   * if (l2.getType().equals(type)) {*
>>>                        return l2;
>>>                    }
>>>                }
>>>                return null;
>>>            }
>>>
>>> but if when cleanUp was called, the unreachable object is l2_2, the
>>> condition
>>>  (l1.get(l2.getType()) == l2) in cleanUp function will not be met.
>>>
>>> I think this is the problem we have, you can see the list will keep
>>> growing
>>> after this.
>>>
>>> -Huai Dong
>>>
>>>
>>>
>>>
>>>
>>>
>>> On Mon, Nov 23, 2009 at 8:15 PM, Stephan Bergmann <
>>> stephan.bergm...@sun.com> wrote:
>>>
>>>  On 11/23/09 07:58, Huaidong Qiu wrote:
>>>>
>>>>  Hi all,
>>>>>
>>>>> We got a problem like this, one of the L2 entry list keep growing
>>>>> consume
>>>>> too much memory.
>>>>>
>>>>> module jurt
>>>>>
>>>>> package com.sun.star.lib.uno.
>>>>> environments.java;
>>>>>
>>>>> the cleanUp member function of class Registry.
>>>>>
>>>>>       // must only be called while synchronized on map:
>>>>>       private void cleanUp() {
>>>>>           for (;;) {
>>>>>               Level2Entry l2 = (Level2Entry) queue.poll();
>>>>>               if (l2 == null) {
>>>>>                   break;
>>>>>               }
>>>>>               // It is possible that a Level2Entry e1 for the OID/type
>>>>> pair
>>>>>               // (o,t) becomes weakly reachable, then another
>>>>> Level2Entry
>>>>> e2
>>>>>               // is registered for the same pair (o,t) (a new
>>>>> Level2Entry
>>>>> is
>>>>>               // created since now e1.get() == null), and only then e1
>>>>> is
>>>>>               // enqueued.  To not erroneously remove the new e2 in
>>>>> that
>>>>> case,
>>>>>               // check whether the map still contains e1:
>>>>>               String oid = l2.getOid();
>>>>>               Level1Entry l1 = getLevel1Entry(oid);
>>>>>               if (l1 != null && l1.get(l2.getType()) == l2) {
>>>>>                   removeLevel2Entry(oid, l1, l2);
>>>>>               }
>>>>>           }
>>>>>       }
>>>>>
>>>>> All those weak reference Level2Entry entries are invalid, the condition
>>>>> (l1.get(l2.getType()) == l2) keeps cleanUp function from removing them
>>>>> from
>>>>> the list.
>>>>>
>>>>> I think if this
>>>>>               // It is possible that a Level2Entry e1 for the OID/type
>>>>> pair
>>>>>               // (o,t) becomes weakly reachable, then another
>>>>> Level2Entry
>>>>> e2
>>>>>               // is registered for the same pair (o,t) (a new
>>>>> Level2Entry
>>>>> is
>>>>>               // created since now e1.get() == null), and only then e1
>>>>> is
>>>>>               // enqueued.
>>>>> happened once then there is no way the condition (l1.get(l2.getType())
>>>>> ==
>>>>> l2) can be true again, because get(l2.getType()) always return the
>>>>> first
>>>>> element in the list, but queue.poll() return the newly released weak
>>>>> reference which can not be the first one in the list.
>>>>>
>>>>>  I fail to see a flaw in the current algorithm.  In the simplest case,
>>>> consider a Level1Entry L that has just one Level2Entry E (for some
>>>> object O,
>>>> OID D, type T) in its list.  Suppose o1 has become unreachable and
>>>> cleanUp
>>>> is called: l2 will be bound to E; oid will be bound to D; l1 will be
>>>> bound
>>>> to L; l2.getType() returns T; l1.get(l2.getType()) returns E, so
>>>> removeLevel2Entry will be called and will indeed remove E from L's list
>>>> (and
>>>> will actually also remove L from the map of Level1Entries).
>>>>
>>>>
>>>>  If weak reference list cleanup mechanism is correct, could please give
>>>>
>>>>> some
>>>>> possible reasons could cause the growing problem of L2 entry list.
>>>>>
>>>>>  You mean, you observe a specific instance of Level1Entry whose list of
>>>> Level2Entries keeps growing without bound?  That sounds strange.  First,
>>>> all
>>>> entries in the list should be for different UNO types supported by the
>>>> respective UNO object, so that should bound the length of the list (no
>>>> UNO
>>>> object probably supports more than a few dozen different UNO types).
>>>>  Second, the only way to have more entries in the list would be to have
>>>> entries referencing different reachable Java objects which would
>>>> nevertheless all have the same UNO OID.  That would sound like a bug
>>>> somewhere.
>>>>
>>>> Maybe you can add debug code to print, for each Level2Entry E in the
>>>> list
>>>> of the given problematic Level1Entry, the following:
>>>> - E.toString()
>>>> - E.getOid()
>>>> - E.getType()
>>>> - E.get()
>>>> to get an idea what that growing list looks like.
>>>>
>>>> -Stephan
>>>>
>>>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscr...@udk.openoffice.org
> For additional commands, e-mail: dev-h...@udk.openoffice.org
>
>

Reply via email to