We are using the smack libraries to send a large volume of message. At any given time we send 10-20 messages per second. The messages range from 200-800 bytes in length.
At the default JVM memory heap size of 64 megs our process runs out of memory in 30-45 minutes. Sooner if we lower the heap size, takes longer if we raise heap size. After several days of debugging we believe we have isolated the leak to the smack libraries.
I have included a test class to demonstrate the behavior. Set your JVM heap memory to 8 megs (-Xmx8m) and you should get ~10400 messages before you run out of memory. Just provide values for userName, serverPassword, serverName, serverPort, roomName, and roomPassword.
Have tested this with 2.1.0 and 2.2.0 and experienced the same behavior.
Has anyone else tried to use smack to send a large volume of messages?
public class LeakTest {
public static void main(String[] args) {
MultiUserChat chatRoom = null;
XMPPConnection chatConnection = null;
String userName = “”;
String serverPassword = “”;
String serverName = “”;
int serverPort = 5223;
String roomName = “”;
String roomPassword = “”;
try {
chatConnection = new SSLXMPPConnection(serverName, serverPort);
chatConnection.login(userName, serverPassword);
chatRoom = new MultiUserChat(chatConnection, roomName + “@conference.” + serverName);
DiscussionHistory discussionHistory = new DiscussionHistory();
discussionHistory.setMaxStanzas(0);
chatRoom.join(userName, roomPassword, discussionHistory, SmackConfiguration.getPacketReplyTimeout());
} catch (XMPPException e) {
e.printStackTrace();
}
NumberFormat memoryFormatter = NumberFormat.getNumberInstance();
int count = 0;
for ( ; ; ) {
try {
chatRoom.sendMessage("");
} catch (XMPPException e) {
e.printStackTrace();
}
if (count++ % 100 == 0) {
System.out.println("Count = " + count);
System.out.println("Free Memory: " + memoryFormatter.format(Runtime.getRuntime().freeMemory()));
System.out.println("Max Memory: " + memoryFormatter.format(Runtime.getRuntime().maxMemory()));
System.out.println("Total Memory: " + memoryFormatter.format(Runtime.getRuntime().totalMemory()));
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}