|
From: <Ric...@i2...> - 2001-01-18 16:51:40
|
Hi Samuel,
(Apologies if the formatting of this message is bizarre, we've been
forced onto Lotus Notes and I can't get it to stop chopping up my lines
in unpredictable places).
Anyhow, I had some more time to look into the problem.
In InternalTables2 you are storing a PyBeanEventProperty reference
into a HashMap, and this seems to prevent garbage collection.
If I change the implementation like so, the memory leak is closed:
protected WeakHashMap adapters;
protected Object getAdapter(Object o,String evc) {
HashMap ads = (HashMap)adapters.get(Integer.toString(o.hashCode
()));
if (ads == null) return null;
return ads.get(evc);
}
protected void putAdapter(Object o,String evc,Object ad) {
HashMap ads = (HashMap)adapters.get(Integer.toString(o.hashCode
()));
if (ads == null) {
ads = new HashMap();
adapters.put(Integer.toString(o.hashCode()),ads);
}
ads.put(evc,ad);
}
Or, alternately, I think you can do the following:
protected WeakHashMap adapters;
protected Object getAdapter(Object o,String evc) {
String key = evc + "$" + o.hashCode();
return adapters.get(key);
}
protected void putAdapter(Object o,String evc,Object ad) {
String key = evc + "$" + o.hashCode();
adapters.put(key,ad);
}
Rich
"Samuele
Pedroni" To: <jyt...@li...>,
<pedroni@inf. <Ric...@i2...>
ethz.ch> cc:
Subject: Re: [Jython-dev] Problems with weak
01/17/01 references?
04:42 PM
Hi.
First of all it seems (but maybe I'm missing something) that java.awt leaks
memory too or at least
to discard things at non-predictable points:
>>> C:\WINDOWS>\jython\mjyth
Jython 2.0beta2 on java1.3.0 (JIT: null)
Type "copyright", "credits" or "license" for more information.
>>> from java.lang import System,ref
>>> from java import awt
>>> f=awt.Frame()
>>> b=awt.Button()
>>> f.add(b);f.pack();f.show()
java.awt.Button[button0,0,0,0x0,invalid,label=]
>>> 0 # clears _
0
>>> w=ref.WeakReference(b)
>>> del b
>>> f.remove(w.get())
>>> System.gc(); System.gc()
>>> w.get() # leak? why?
java.awt.Button[button0,4,28,136x23,label=]
>>> 0
0
>>> f.dispose()
>>> del f
>>> System.gc()
>>> w.get()
>>>
f.remove() + System.gc() seems not enough in order to discard b?
This is related to the tables because as long as b is around, its adapters
will
be too.
Indipendently of this: the table can leak memory in some cases (it should
be
possible to fix this but after 2.0):
Jython 2.0beta2 on java1.3.0 (JIT: null)
Type "copyright", "credits" or "license" for more information.
>>> from java import awt
>>> import itd
>>> from java.lang import System
>>> b=awt.Button(); b.actionPerformed = lambda e: b
>>> itd.ad()
['java.awt.event.ActionListener']
>>> del b
>>> System.gc()
>>> itd.ad()
[]
>>> # no leaks with this code but
>>> b=awt.Button(); b.actionPerformed = lambda e,me=b: None
>>> itd.ad()
['java.awt.event.ActionListener']
>>> del b
>>> System.gc()
>>> itd.ad()
['java.awt.event.ActionListener']
>>> # so we get a memory leak
In this case the listener function hold a ref to the source object, to
solve
this the table should (carefully) use weak-refs for values
too. In the meantime this kind of code can be avoided given that events
come
with source info.
regards, Samuele Pedroni.
|