[SNMP4J] Memory Leak in SNMP4J Agent

Frank Fock fock at agentpp.com
Fri Aug 19 20:43:05 CEST 2005


Hi Mark,

Thanks for reporting this leak. It can be easily fixed by patching the
dipatchCommand method of the CommandProcessor class as
follows:

        if (req.isComplete()) {
          // add the following line to remove memory leak:
          requestList.remove(req);
          // send response
          sendResponse(command, req);
        }

The request list is currently not used, but will (probably) be used be the
AgentX master agent.

Best regards,
Frank

robert.m.dabell at L-3com.com wrote:

>I have a SNMP manager that is querying data from a modified SNMP4J
>TestAgent.  I left it running over night and when I returned the Heap had
>run out of memory for the Agent.  Today, I ran a little test to see if I
>could repeat the problem and using JConsole, I have noticed that the memory
>usage of the agent keeps growing while messages are being sent and doesn't
>recover the memory when the manager stops.  
>
>Using the -Dcom.sun.management.jmxremote option with the TestAgent (i.e.
>java -Dcom.sun.management.jmxremote -cp snmp4j-agent.jar
>org.snmp4j.agent.test.TestAgent), run JConsole (included with JDK 1.5) and
>run the following code, which will send a GET sysUpTime PDU as fast as it is
>receives the previous request's response.  On the JConsole you will see an
>increase in memory usage and it will not decrease when the Manager is
>shutdown.  The TestAgent also dies after about 8 1/2 minutes with the Out of
>memory exception (default 64M heap).  All I am doing with this test is
>reading one variable over and over.  Memory shouldn't be an issue.
>
>import java.io.IOException;
>
>import org.snmp4j.CommunityTarget;
>import org.snmp4j.PDU;
>import org.snmp4j.Snmp;
>import org.snmp4j.TransportMapping;
>import org.snmp4j.event.ResponseEvent;
>import org.snmp4j.event.ResponseListener;
>import org.snmp4j.mp.MPv3;
>import org.snmp4j.mp.MessageProcessingModel;
>import org.snmp4j.mp.SnmpConstants;
>import org.snmp4j.security.SecurityModels;
>import org.snmp4j.security.SecurityProtocols;
>import org.snmp4j.security.USM;
>import org.snmp4j.smi.Address;
>import org.snmp4j.smi.GenericAddress;
>import org.snmp4j.smi.OID;
>import org.snmp4j.smi.OctetString;
>import org.snmp4j.smi.Variable;
>import org.snmp4j.smi.VariableBinding;
>import org.snmp4j.transport.DefaultUdpTransportMapping;
>
>
>public class TestManager{
>  private Snmp snmp;
>  
>  public TestManager(String host, int port){
>    try {
>      Address address = GenericAddress.parse("udp:"+host+"/"+port);
>      System.out.println("Address = " + address);
>      
>      
>      TransportMapping transport = new DefaultUdpTransportMapping();
>      snmp = new Snmp(transport);
>      transport.listen();
>
>      MessageProcessingModel mp =
>snmp.getMessageProcessingModel(MessageProcessingModel.MPv2c);
>      
>      
>      USM usm = new USM(SecurityProtocols.getInstance(), new
>OctetString(MPv3.createLocalEngineID()), 0);
>      SecurityModels.getInstance().addSecurityModel(usm);
>      
>      
>      
>      CommunityTarget target = new CommunityTarget();
>      
>      
>      target.setCommunity(new OctetString("public"));
>        
>            
>      target.setAddress(address);
>      target.setRetries(1);
>      target.setTimeout(100);
>      target.setVersion(SnmpConstants.version2c);
>      
>      
>      while(true){
>        PDU pdu = new PDU();
>        pdu.setType(PDU.GET);
>        VariableBinding varbind = new
>VariableBinding(SnmpConstants.sysUpTime);
>        pdu.add(varbind);
>        synchronized(snmp){
>          snmp.send(pdu, target,null, listener);
>        
>          try {
>            snmp.wait();
>          } catch (InterruptedException e) {
>           
>            e.printStackTrace();
>          }
>        }
>      }
>     
>    } catch (IOException e) {
>      
>      e.printStackTrace();
>    }
>   
>    
>  }
>  
>  private ResponseListener listener = new ResponseListener(){
>    VariableBinding varbind = null;
>    Variable var = null;
>    Object value = null;
>  
>    public void onResponse(ResponseEvent event) {
>      // Always cancel async request when response has been received
>      // otherwise a memory leak is created! Not canceling a request
>      // immediately can be useful when sending a request to a broadcast
>      // address.
>      ((Snmp)event.getSource()).cancel(event.getRequest(), this);
>      System.out.println("Received response PDU is: "+event.getResponse());
>      
>      PDU rpdu = event.getResponse();
>      
>      
>      if (rpdu != null){
>        varbind = rpdu.get(0);
>        OID oid = varbind.getOid();
>        if (oid.equals(SnmpConstants.sysUpTime)){
>          var = varbind.getVariable();
>          System.out.println("uptime = " + var);
>        }
>        
>      } else {
>        System.out.println("PDU timed out");
>      }
>      synchronized(snmp){
>        snmp.notifyAll();
>      }
>      
>      
>    }
>  };
>  
>  
>  
>  public static void main(String[] args) {
>    new TestManager(args[0], Integer.parseInt(args[1]));
>  }
>
>}
>
>
>This test manager is extreme as far as frequency of requests are concerned
>but the application that I am implementing would only have 1 hr run time
>before the agent runs out of memory and stops working.
>
>
>
>R. Mark DaBell
>
>_______________________________________________
>SNMP4J mailing list
>SNMP4J at agentpp.org
>http://lists.agentpp.org/mailman/listinfo/snmp4j
>
>
>  
>


-- 
AGENT++
http://www.agentpp.com
http://www.mibexplorer.com
http://www.mibdesigner.com





More information about the SNMP4J mailing list