You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@hivemind.apache.org by ji...@apache.org on 2004/04/07 16:08:43 UTC

[jira] Commented: (HIVEMIND-2) EventListenerList leaks memory

The following comment has been added to this issue:

     Author: Geoff Longman
    Created: Wed, 7 Apr 2004 7:07 AM
       Body:
Just to make it clear, Added two patches, one is for the EventListenerList test case, and the other is patch to EventListenerList itself (fixes problem).
---------------------------------------------------------------------
View this comment:
  http://issues.apache.org/jira/browse/HIVEMIND-2?page=comments#action_28006

---------------------------------------------------------------------
View the issue:
  http://issues.apache.org/jira/browse/HIVEMIND-2

Here is an overview of the issue:
---------------------------------------------------------------------
        Key: HIVEMIND-2
    Summary: EventListenerList leaks memory
       Type: Bug

     Status: Unassigned
   Priority: Major

    Project: HiveMind
 Components: 
             framework
   Versions:
             1.0

   Assignee: 
   Reporter: Geoff Longman

    Created: Tue, 6 Apr 2004 7:24 PM
    Updated: Wed, 7 Apr 2004 7:07 AM
Environment: jdk 1.4.1, mulitple OS's (Redhat 9, Win2k), multiple servlet containers (Jetty 4.2.8 and Tomcat 4.1.27)

Description:
Running a Tapestry app using Hivemind. We are getting out of memory errors after 5 to 10 minutes. There is only one user logged into the app at any one time.

Built Hivemind from src in commons sandbox cvs.

Using the jdk's -Xrunhprof tool.

It looks like there is a memory leak
in EventListener.copyOnWrite().

the raw data we are seeing...

TRACE 40863:

org.apache.hivemind.util.EventListenerList.copyOnWrite(EventListenerList.jav
a:163)

org.apache.hivemind.util.EventListenerList.removeListener(EventListenerList.
java:135)

org.apache.hivemind.util.EventListenerList.removeListener(EventListenerList.
java:127)

org.apache.hivemind.service.impl.ThreadEventNotifierImpl.removeThreadCleanup
Listener(ThreadEventNotifierImpl.java:52)


           percent         live       alloc'ed  stack class
  rank   self  accum    bytes objs   bytes objs trace name
     1 80.80% 80.80% 188744400    5 377489864   89 40863 java.lang.Object

 The same info as above:

 just a bit easier to read!

 rank: 1
 percent self: 80.80%
 percent accum: 80.80%
 live bytes: 188744400
 live objs: 5
 alloc's bytes: 377489864
 alloc's objs: 89
 stack trace: 40863
 class name: java.lang.Object

What follows are observations from a colleague working this problem:

----- Original Message ----- 
From: "Chris Justus" 
To: <glongman@>
Sent: Tuesday, April 06, 2004 5:02 PM
Subject: EventListenerList code...


> Looking over the code...
> 
> removeListener calls copyOnWrite... The problem is that if there is an 
> iterator when we remove a listener...
> Suppose that we currently have _listeners.length with a size 5, and an 
> iterator ...
> 
> (1) size = 5
> (4) nominalSize becomes 10...
> (5) newSize is the max of our required size or the nominal size... so 
> newSize is 10...
> 
> Call removeListener enough times, and you've got some pretty big arrays 
> of objects... (doubling in size every time these events occur...)
> 
> Lines from EventListenerList.java copyOnWrite():
> ...
>  (1)       int size = _listeners == null ? 0 : _listeners.length;
> 
>  (2)       if (_iteratorCount > 0 || size < requiredSize)
>  (3)      {
>  (4)          int nominalSize = (size == 0) ? START_SIZE : 2 * size;
> 
>  (5)            int newSize = Math.max(requiredSize, nominalSize);
> 
> (6)            Object[] newListeners = new Object[newSize];
> ...
> 
> 

We're not seeing removeListener called at the end of every request on every thread in the servlet container. But, once a thread's EventListenerList starts growing, it does so for every request afterward.

I did some "back of a napkin" figurin' and as the array starts at size 5 and doubles whenever removeListener is called then the array size is approx 105 million after 18 iterations. I don't know how the jdk implementation works for arrays but if each cell is a 32 bit pointer, 105 million * 4 = 420 MB. 

I have a test case that reproduces the error. Lets see if JIRA will let me attach it.....




---------------------------------------------------------------------
JIRA INFORMATION:
This message is automatically generated by JIRA.

If you think it was sent incorrectly contact one of the administrators:
   http://issues.apache.org/jira/secure/Administrators.jspa

If you want more information on JIRA, or have a bug to report see:
   http://www.atlassian.com/software/jira


---------------------------------------------------------------------
To unsubscribe, e-mail: hivemind-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: hivemind-dev-help@jakarta.apache.org