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