[Biojava-dev] memory leak

Michael Heuer heuermh at acm.org
Wed Jan 26 23:49:21 EST 2005


On Thu, 27 Jan 2005 mark.schreiber at group.novartis.com wrote:

> Following a tip off from Rainer I have discovered that there is a memory
> leak in BioJava caused by calling subList() or subStr() on
> SimpleSymbolLists
>
> The simple routine below will run for a long time but if left it will
> eventually cause an out of memory error.
>
>   public void run() throws Exception{
>     SymbolList sl =
> DNATools.createDNA("acgctcgagctcgagctagcgactacgagcgctgcag");
>     while(true){
>       SymbolList sl2 = sl.subList(1,12);
>     }
>   }
>
>
> I ran this through a profiller and found the following:
>
> > 99% of the CPUs time is taken up calling SimpleSymbolList.finalize(),
> all of this is due to a call to AbstractChangeable.removeChangeListener().
> All the calls to finalize() are to be expected as the variable sl2 gets
> garbage collected a lot but the burden of the removeChangeListener is
> unexpected. 99% in finalize() is pretty bad when I would have thought the
> sublist operations would have been more expensive.
>
> Overtime the stack becomes overloaded with tens of thousands of
> WeakReference instances that are apparently not that weak as the GC is not
> touching them.
>
> 99.72% of these WeakReferences are being generated by calls to
> ChangeSupport.addChangeListener() They are being stored in a HashMap that
> is taking a bit of a punishing!

That seems odd to me, ChangeSupport in cvs doesn't add to or remove from a
HashMap, it uses parallel arrays

  /**
   * Add a listener that will be informed of changes of a given type (and
it's subtypes)
   *
   * @param cl  the ChangeListener
   * @param ct  the ChangeType it is to be informed of
   */
  public void addChangeListener(ChangeListener cl, ChangeType ct) {
    if (ct == null) {
      throw new NullPointerException("Since 1.2, listeners registered for
the null changetype are not meaningful.  Please register a listener for
ChangeType.UNKNOWN instead");
    }

    if(isUnchanging(ct)) {
      return;
    }

    synchronized(this) {
      growIfNecessary();
      types[listenerCount] = ct;
      listeners[listenerCount] = new WeakReference(cl);
      listenerCount++;
    }
  }

But perhaps that is besides the point -- why are any of these
change listeners being added at all?  Maybe the orginal symbol list
listens for changes in each of its sublists?

   michael


>
> It would seem that the change support mechanism somewhere has a memory
> leak and is not releasing references from the HashMap. It is also placing
> a very heavy burden on the CPU.
>
> My java is 1.4.2 and biojava from CVS
>
> Can anyone think of what might be going wrong?
>
> - Mark
>
> Mark Schreiber
> Principal Scientist (Bioinformatics)
>
> Novartis Institute for Tropical Diseases (NITD)
> 10 Biopolis Road
> #05-01 Chromos
> Singapore 138670
> www.nitd.novartis.com
>
> phone +65 6722 2973
> fax  +65 6722 2910
>
> _______________________________________________
> biojava-dev mailing list
> biojava-dev at biojava.org
> http://biojava.org/mailman/listinfo/biojava-dev
>



More information about the biojava-dev mailing list