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: [email protected] For additional commands, e-mail: [email protected]
