[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