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 > >