I think that I have figured out the 'Out Of Memory Errors' that I have been recently enjoying with JMeter 1.6alpha on Solaris 2.7, with Java 1.3.
 
Apparently the LinkedList class has a flaw in it (or perhaps my knowledge of the LinkedList is lacking - as I said, I am a relative newbie in this development area).
 
 
Seems that when the sample is done, the size of the queue is big.  I would have expected it to be zero (or close to zero).  
Some further investigation turned up the following:
 
It appears that the LinkedList can get into a state where it throw a NoSuchElementException when removeFirst() is called, even when the list is not empty.
 
To test this, I changed the SampleQueue class a bit:
private class SampleQueue extends Thread {
  private LinkedList occurredQ = new LinkedList();
  public SampleQueue() {
   Debug.println("SampleQueue created...");
  }
  public synchronized void sampleOccurred(SampleEvent e) {
   occurredQ.addLast(e);
   this.notify();
  }
  public long size() {
   return occurredQ.size();
  }
  public void run() {
      Debug.println("Event Queue has started running...", Debug.MIN_PRIORITY);
   SampleEvent event = null;
   long sample = 1;
   long iteration = 1;
   long exception = 1;
   while(true) {
    if (++iteration%1000==0)
     Debug.println("Processing iteration #"+iteration+" of the Event Queue", Debug.MIN_PRIORITY);
    //get the first available item in the queue...
    try {
     event = (SampleEvent)occurredQ.removeFirst();
        if (++sample%1000==0)
         Debug.println("Samples processed: "+sample, Debug.MIN_PRIORITY);
    } catch (NoSuchElementException nseex) {
     if (!occurredQ.isEmpty()) {
      Debug.println("NoSuchElementException thrown when queue not empty (Queue size: " + occurredQ.size() + ")",
       Debug.MIN_PRIORITY);
     }
     if (++exception%1000==0) {
      Debug.println("Exception #"+exception+" has occurred", Debug.MIN_PRIORITY);
      nseex.printStackTrace();
     }
     waitForSamples();
     continue;
    } catch (Exception ex) {
     ex.printStackTrace();
     exception++;
     continue;
    }
    try {
     if(event != null) {
      Iterator iter = listeners.iterator();
      while (iter.hasNext()) {
       ((SampleListener)iter.next()).sampleOccurred(event);
      }
      iter = remoteListeners.iterator();
      while (iter.hasNext()) {
       try {
        ((RemoteSampleListener)iter.next()).sampleOccurred(event);
       } catch (Exception ex) {
        ex.printStackTrace();
       }
      }
     }
     else
      waitForSamples();
    } catch (Throwable ex) {
     ex.printStackTrace();
    }
    this.yield();
   }
  }
  private synchronized void waitForSamples()
  {
   try {
    this.wait();
   } catch (Exception ex) {
    ex.printStackTrace();
   }
  }
 }
(Note that the
I found that a few samples would be taken, and then I would start to get a stream of
 
NoSuchElementException thrown when queue is not empty (Queue size: 516)
 
Once this occurs, the items in the queue are never retrieved, and the queue continues to grow.   Even with a 1 GB heap, it does not take long before we run out of system resources (at 900+ sampleEvents per second).
 
I am doing the majority of my work on a Sun Enterprise 420R, with 4 450MHz CPUs and 2 GB RAM.   Perhaps these issues are not as visible on machines with smaller horsepower.
 
Can anyone please either a) clear up any misconceptions that I may have regarding the use of the java LinkedList or b) please suggest an alternate solution to the use of the LinkedList in this implementation?
 
Thanks in Advance.
Jamie

Jamie Davidson, Product Verification Specialist
Bridgewater Systems Corporation
555 Legget Drive
Suite 800, Tower A
Kanata Ontario K2K 2X3
Phone: (613) 591-6655
Fax:      (613) 591-6656

 

Reply via email to