OutOfMemory at PubSub mode

Hi, all.

We deploy an openfire server at our Linux OS, login in with a user, create a pubsub node.

Then I start a timer job to publish message to this node, this timer job publish a message to node every second.

Then I login the openfire Admin Console, I can see the used memory increasing more and more, from 70MB to 300MB. And then the server throw an OutOfMemoryError, and refuse to receive connection too.

Will anybody know how to resolve this problem?

Here is my IQ for create node:

public class CreateNodeRequest extends IQ {

private String topic;

@Override

public String getChildElementXML() {

StringBuilder buf = new StringBuilder();

      buf.append("<pubsub xmlns='[http://jabber.org/protocol/pubsub](http://jabber.org/protocol/pubsub)'>");

buf.append("<create node=");

buf.append("’" + topic + “’/>”);

buf.append("");

buf.append("");

buf.append("");

return buf.toString();

}

public String getTopic() {

return topic;

}

public void setTopic(String topic) {

this.topic = topic;

}

}

And here is my IQ for send pubsub message:

public class PublishRequest extends IQ {

private String message;

private String topic;

@Override

public String getChildElementXML() {

StringBuilder buf = new StringBuilder();

      buf.append("<pubsub xmlns='[http://jabber.org/protocol/pubsub](http://jabber.org/protocol/pubsub)'>");

buf.append("<publish node="" + topic + “”>");

buf.append("");

buf.append(message);

buf.append("");

buf.append("");

buf.append("");

return buf.toString();

}

public String getMessage() {

return message;

}

public void setMessage(String message) {

this.message = message;

}

public String getTopic() {

return topic;

}

public void setTopic(String topic) {

this.topic = topic;

}

}

Hi,

are you using the embedded database or an external one?

LG

Isn’t the default node config to have persist_items = false? I would think the database would not make any difference in this case since only the last item is stored anyway, and it only gets stored once every couple of minutes.

We use external MySQL database at Linux OS.

And I trying to use embeded database at Windows OS, and the result the same. The used memory is growing more and more.

I set persist_items to false, and the result the same. And here is my IQ for create node:

public class CreateNodeRequest extends IQ {

private String topic;

@Override

public String getChildElementXML() {

StringBuilder buf = new StringBuilder();

      buf.append("<pubsub xmlns='[http://jabber.org/protocol/pubsub](http://jabber.org/protocol/pubsub)'>");

buf.append("<create node=");

buf.append("’" + topic + “’/>”);

buf.append("");

buf.append(" ");

buf.append("");

      buf.append("<value>[http://jabber.org/protocol/pubsub#node_config](http://jabber.org/protocol/pubsub#node_config)</value>");

buf.append("");

buf.append(“LiveScore”);

buf.append(“1”);

buf.append(“1”);

buf.append(“0”);

buf.append(“10”);

buf.append(“open”);

buf.append(“publishers”);

buf.append(“never”);

buf.append(“false”);

buf.append(“0”);

buf.append(“0”);

buf.append(“0”);

buf.append(“0”);

buf.append(“1028”);

      buf.append("<field var='pubsub#type'><value>[http://www.w3.org/2005/Atom](http://www.w3.org/2005/Atom)</value></field>");

buf.append("");

      buf.append("<value>[http://jabxslt.jabberstudio.org/atom_body.xslt](http://jabxslt.jabberstudio.org/atom_body.xslt)</value>");

buf.append("");

buf.append("");

buf.append("");

buf.append("");

return buf.toString();

}

public String getTopic() {

return topic;

}

public void setTopic(String topic) {

this.topic = topic;

}

}

Hi,

I can not reproduce this. I see that the tenured memory does increase but a simple GC frees it. My GC log (with -Xmx32m) looks like this:

1278.173: [GC 1278.173: [DefNew: 3115K->171K(3264K), 0.0036900 secs] 30929K->28816K(32448K), 0.0038030 secs]
1278.342: [GC 1278.342: [DefNew: 3113K->3113K(3264K), 0.0000220 secs]1278.342: [Tenured: 28645K->10436K(29184K), 0.1826320 secs] 31758K->10436K(32448K), 0.1827940 secs]
1278.652: [GC 1278.652: [DefNew: 2944K->198K(3264K), 0.0035780 secs] 13380K->11402K(32448K), 0.0036870 secs]

LG

PS: I’m using this code:

String topic = "qwerty";
    String XMPPDomain = "localhost";
    private Openfire_OOM_Pubsub_Test() throws Exception
    {
        XMPPConnection conn1 = new XMPPConnection(XMPPDomain);
        conn1.login("foo", "bar");           Thread.sleep(500);
          IQ iq = new IQ()
          {
               public String getChildElementXML()
               {
                    StringBuilder buf = new StringBuilder();
                    buf.append("<pubsub xmlns='http://jabber.org/protocol/pubsub'>");
                    buf.append("<create node='" + topic + "'/>");
                    buf.append("<configure>");
                    buf.append(" <x xmlns='jabber:x:data' type='submit'>");
                    buf.append("<field var='FORM_TYPE' type='hidden'>");
                    buf.append("<value>http://jabber.org/protocol/pubsub#node_config</value>");
                    buf.append("</field>");
                    buf.append("<field var='pubsub#title'><value>LiveScore</value></field>");
                    buf.append("<field var='pubsub#deliver_notifications'><value>1</value></field>");
                    buf.append("<field var='pubsub#deliver_payloads'><value>1</value></field>");
                    buf.append("<field var='pubsub#persist_items'><value>0</value></field>");
                    buf.append("<field var='pubsub#max_items'><value>10</value></field>");
                    buf.append("<field var='pubsub#access_model'><value>open</value></field>");
                    buf.append("<field var='pubsub#publish_model'><value>publishers</value></field>");
                    buf.append("<field var='pubsub#send_last_published_item'><value>never</value></field>");
                    buf.append("<field var='pubsub#presence_based_delivery'><value>false</value></field>");
                    buf.append("<field var='pubsub#notify_config'><value>0</value></field>");
                    buf.append("<field var='pubsub#notify_delete'><value>0</value></field>");
                    buf.append("<field var='pubsub#notify_retract'><value>0</value></field>");
                    buf.append("<field var='pubsub#notify_sub'><value>0</value></field>");
                    buf.append("<field var='pubsub#max_payload_size'><value>1028</value></field>");
                    buf.append("<field var='pubsub#type'><value>http://www.w3.org/2005/Atom</value></field>");
                    buf.append("<field var='pubsub#body_xslt'>");
                    buf.append("<value>http://jabxslt.jabberstudio.org/atom_body.xslt</value>");
                    buf.append("</field>");
                    buf.append("</x>");
                    buf.append("</configure>");
                    buf.append("</pubsub>");
                    return buf.toString();
               }
          };
          iq.setType(IQ.Type.SET);
          iq.setTo("pubsub."+ XMPPDomain);
          // System.out.println(iq.toXML());
          conn1.sendPacket(iq);           Thread.sleep(500);
          IQ iq2 = new IQ()
          {
               public String getChildElementXML()
               {
                    StringBuilder buf = new StringBuilder();
                    buf.append("<pubsub xmlns='http://jabber.org/protocol/pubsub'>");
                    buf.append("<publish node='" + topic + "'>");
                    buf.append("<item><entry xmlns='http://www.w3.org/2005/Atom'><title>Soliloquy</title><summary>s</summary><link rel='alternate' type='text/html' href='http://example.com/2003/12/13/atom03'/><id>tag:example.com,2003:entry-32397</id><published>2003-12-13T18:30:02Z</published><updated>2003-12-13T18:30:02Z</updated></entry></item>");
                    buf.append("</publish>");
                    buf.append("</pubsub>");
                    return buf.toString();
               }
          };
          iq2.setType(IQ.Type.SET);
          iq2.setTo("pubsub."+ XMPPDomain);
          // System.out.println(iq.toXML());
          for (int i = 0; i < 100000; i++)
          {
               conn1.sendPacket(iq2);
               Thread.sleep(15);
          }
          conn1.close();
     }

Hi.

I have another question.

I can’t understand what does ‘JID’ mean at pubsub mode, it seems there are three type of JID:

(1) a login user, for example, jiangyubao@gmail.com

(2) another example:

iq.setTo(“pubsub.it.ma.cx”);

And what does this code means? Is it a server name? Can I replace it with “localhost”?

Hi,

I did update the code and did replace it.ma.cx with localhost. “localhost” should be replaced by your xmpp.domain.

  • it seems there are three type of JID:*

http://xmpp.org/extensions/xep-0029.html#sect-id2252918

::= ["@"]["/"]

I did copy the example from http://xmpp.org/extensions/xep-0060.html#publisher-publish-request - there no node nor resource is specified.

LG

Hi, Do you know how to enable anonymous subscribe?

How can I modify openfire’s source file to enable it, or can you send me a openfire.jar that support snonymous subscribe?

I want to modify openfire source file to enable it, but I can not find such switch to open?

Thanks a lot.

Hi,

you may want to ask such a question in the Openfire Dev forum.

Can you post some complete code which allows to reproduce the OutOfMemory issue?

LG

You run the following code for 10 minutes, And you will see the used memory can increase to 97%.

import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.packet.IQ; public class PubsubTest {
     public PubsubTest()throws Exception{
          XMPPConnection.DEBUG_ENABLED=true;
          String serverName="web169";
          XMPPConnection connection = new XMPPConnection(serverName);
          
          connection.connect();
          connection.login("pub", "pub");
          Thread.sleep(500);
          final String topic="topic1";
          String to=serverName;
        IQ iq = new IQ()
        {
             public String getChildElementXML()
             {
                  StringBuilder buf = new StringBuilder();
                  buf.append("");
                  buf.append("");
                  buf.append("");
                  buf.append(" ");
                  buf.append("");
                  buf.append("http://jabber.org/protocol/pubsub#node_config");
                  buf.append("");
                  buf.append("LiveScore");
                  buf.append("0");
                  buf.append("0");
                  buf.append("0");
                  buf.append("1");
                  buf.append("open");
                  buf.append("publishers");
                  buf.append("never");
                  buf.append("false");
                  buf.append("0");
                  buf.append("0");
                  buf.append("0");
                  buf.append("0");
                  buf.append("1");
                  buf.append("http://www.w3.org/2005/Atom");
                  buf.append("");
                  buf.append("http://jabxslt.jabberstudio.org/atom_body.xslt");
                  buf.append("");
                  buf.append("");
                  buf.append("");
                  buf.append("");
                  return buf.toString();
             }
        };
        iq.setType(IQ.Type.SET);
        iq.setTo(to);
       // I add a from JID to this IQ.
        iq.setFrom("pub@"+serverName);
        connection.sendPacket(iq);
        Thread.sleep(500);
        IQ iq2 = new IQ()
        {
             public String getChildElementXML()
             {
                  StringBuilder buf = new StringBuilder();
                  buf.append("");
                  buf.append("");
                  buf.append("stag:example.com,2003:entry-323972003-12-13T18:30:02Z2003-12-13T18:30:02Z");
                  buf.append("");
                  buf.append("");
                  return buf.toString();
             }
        };
        iq2.setType(IQ.Type.SET);
        iq2.setTo(to);
        // I add a from JID to this IQ.
        iq2.setFrom("pub@" + serverName);
        for (int i = 0; i < 10000000; i++)
        {
             connection.sendPacket(iq2);
             Thread.sleep(100);
        }
        connection.disconnect();
           }
     public static void main(String[] args) throws Exception {
          new PubsubTest();
     }
}

I post a screen copy here.

I have to add a from_JID to the IQ when create node or send message to node.

If I don’t add a from_JID to it, I can’t subscribe it, and here is my subscribe code:

private String server = “web169”;

private String topicOwner=“pub”;

private String user = “jianygb”;

private String password = “jianygb”;

private String topic = “topic1”;

private XMPPConnection connection;

SubscribeRequest subscribeRequest = new SubscribeRequest();

subscribeRequest.setFrom(user + “@” + server);

subscribeRequest.setTo(this.server);

subscribeRequest.setTopic(topic);

subscribeRequest.setJid(user + “@” + this.server);//The JID is the node owner that can send message to the node.

subscribeRequest.setType(IQ.Type.SET);

connection.sendPacket(subscribeRequest);

This appears to have a couple of problems. First of all neither IQ packet you are creating looks correct. Second, you need to set the to in your IQ packet to pubsub.servername. I am guessing that this is where the memory leak is occurring because wherever the packets are getting routed cannot process the packet type.

You can also try using the pubsub library attached here instead of manually creating the packets.