Memory leak Using IMQ 3.6SP4 or 4.0
Hi, I just commit this bug to sun (that will take some time), but I was expecting to share this problem to avoid people losing time like me : ) and maybe if some other developer have some workaround... thanks!
A DESCRIPTION OF THE PROBLEM :
if you configure a queue with a max number of message and use "remove oldest" or "remove lower priority"
as a limit behavior (with or without using dead message queue) and then start to produce messages in that queue, it's possible to observer
a memory leak in the java heap space (using jconsole).
FULL PRODUCT VERSION :
This bug is reported using:
Sun Java(tm) System Message Queue 4.0
Sun Microsystems, Inc.
Version: 4.0 (Build 28-a)
Compile: Tue May 2 09:50:18 PDT 2006
Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved.
SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
This product includes code licensed from RSA Data Security.
=============================================================================== =
Java Runtime: 1.5.0_04 Sun Microsystems Inc. /usr/java/jdk1.5.0_04/jre
[26/Oct/2006:12:17:44 CLST] License: Sun Java(tm) System Message Queue 4.0 Enterprise Edition
and also... using:
Sun Java(tm) System Message Queue 3 2005Q4
Sun Microsystems, Inc.
Version: 3.6 SP3 (Build 02-A)
Compile: Wed Jun 22 15:30:03 PDT 2005
Copyright 漏 2005 Sun Microsystems, Inc. All rights reserved.
Use is subject to license terms.
This product includes code licensed from RSA Data Security.
=============================================================================== =
Java Runtime: 1.5.0_09 Sun Microsystems Inc. /opt/jdk1.5.0_09/jre
[26/Oct/2006:11:50:57 CLST] License: Sun Java(tm) System Message Queue 3.6 Enterprise Edition
FULL OS VERSION :
Linux wolverine 2.6.9-42.0.2.EL #1 Tue Aug 22 23:56:05 CDT 2006 i686 i686 i386 GNU/Linux
EXTRA RELEVANT SYSTEM CONFIGURATION :
2 GB of RAM
Modified /opt/sun/mq/bin/imqbrokerd script...
Added...
_jconsole="-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.port=9501"
Modified:
_jvm_args="$_jconsole $_def_jvm_args $_jvm_args -Dimq.home=$imq_home -Dimq.varhome=$imq_varhome -Dimq.etchome=$imq_etchome -Dimq.libhome=$imq_sharelibimq_home"
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1.- First create a destinantion or your test machine, with the following properties:
-
Host Primary Port
-
localhost7676
Destination Name SUN_TEST
Destination Type Queue
Destination State RUNNING
Created Administratively true
Current Number of Messages
Actual0
Held in Transaction0
Current Message Bytes
Actual0
Held in Transaction0
Current Number of Producers1
Current Number of Active Consumers0
Current Number of Backup Consumers0
Max Number of Messages100
Max Total Message Bytesunlimited (-1)
Max Bytes per Messageunlimited (-1)
Max Number of Producers10
Max Number of Active Consumers10
Max Number of Backup Consumers0
Limit BehaviorREMOVE_OLDEST
Consumer Flow Limit1000
Is Local Destinationfalse
Local Delivery is Preferredfalse
Use Dead Message Queuefalse
Successfully queried the destination.
2.- Modifief imqbrokerd script to observe the heap usage:
Add...
_jconsole="-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.port=9501"
Modified:
_jvm_args="$_jconsole $_def_jvm_args $_jvm_args -Dimq.home=$imq_home -Dimq.varhome=$imq_varhome -Dimq.etchome=$imq_etchome -Dimq.libhome=$imq_sharelibimq_home"
3.- Init IMQ and connect using JConsole, observe "Memory", Heap Usage. Connect to the port 9501 (as you configure in the above step).
4.- Use this simple java programan (imq.jar and jms.jar are required in the classpath):
import javax.jms.QueueConnection;
import javax.jms.QueueSender;
import javax.jms.QueueSession;
import javax.jms.Session;
import javax.jms.TextMessage;
import java.util.Date;
publicclass IMQBug
{
String COLA_OUT ="SUN_TEST";
int totalMsg = 20000;//total number of messages sended
int pauseMsg = 100;//pause in miliseconds between messages
String Server ="192.168.168.70";//imq test server
String message ="anita lava la tina anita lava la tina anita lava la tina anita lava la tina anita lava la tinaanita lava la tina anita lava la tina anita lava la tina anita lava la tina anita lava la tina";
////////////////////////////////////
QueueSession myQSess=null;
QueueSendermyQueueSender =null;
public IMQBug()
{
//Make the connection
conectaJMS();
System.out.println(new Date());
//Send messages
for(int i=0 ; i<totalMsg; i++)
{
sendCommand(message);
if(i % (int)(totalMsg/100) == 0)
System.out.println((100.0*i/totalMsg) +"% of the TesT");
try
{
Thread.sleep(pauseMsg);
}
catch(Exception e){}
}
System.out.println(new Date());
//ok, i don't close everything ;)
System.exit(0);
}
publicvoid sendCommand(String command){
try{
//Create and send a message to the queue.
TextMessage myTextMsg = myQSess.createTextMessage();
myTextMsg.setText(command);
myQueueSender.send(myTextMsg);
}
catch(Exception e){
System.out.println("ERROR: Sending...");
e.printStackTrace();
}
}
publicvoid conectaJMS(){
try{
com.sun.messaging.QueueConnectionFactory fq=new com.sun.messaging.QueueConnectionFactory();
fq.setProperty("imqBrokerHostName", Server);
fq.setProperty("imqBrokerHostPort","7676");
QueueConnection conexion=fq.createQueueConnection();
myQSess= conexion.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
com.sun.messaging.Queue cola=new com.sun.messaging.Queue();
cola.setProperty("imqDestinationName",COLA_OUT);
myQSess= conexion.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
//Create a QueueSender message producer.
myQueueSender=myQSess.createSender((javax.jms.Queue)cola);
conexion.start();
System.out.println("INFO: JMS OK");
}
catch(Exception e)
{
System.out.println("ERROR: JMS Connection");
e.printStackTrace();
}
}
publicstaticvoid main(String[] args)
{
new IMQBug();
}
}
5.- Watch JCONSOLE ( New Connection / Remote /) setting to the test server you java in the 9501 port, an wait for 20 minutes, you will see a memory increase (faster if you increase speed)
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
If the number of message in a queue is limited, the memory usage also must be stable around the max number of message allowed in the queue. In the JConsole graph of Heap Memory Usage I was specting a stable (I'm talking about hours not second).
ACTUAL -
The IMQ memory usage increase until the red condition, then just crash, and then all the company applications crash, VERY BAD BUG!.
SERVER LOG FILE :
THis is a bug just in IMQ
REPRODUCIBILITY :
This bug can be reproduced always.
IMQ CONFIGURATION:
imq.destination.DMQ.truncateBody=true
imq.instanceconfig.version=300>

