2 Replies Latest reply on Apr 5, 2006 4:24 PM by sumitsu

    Too many threads for message queue?

    sumitsu

      Hi,

      I currently have a JBoss EJB application which employs 7 message queues using MDBs with container-managed transactions, to which messages are posted via JNDI from a stateless session bean within the same application. I have recently begun encountering OutOfMemoryErrors during periods of heavy processing, when large numbers of messages are posted to the queues; running JBoss with Java's heap profiling tools (big performance hit) reveals that the error generally begins to occur when the number of simultaneously running threads reaches 75 to 80. After examining the Java profiler log files, I found a long series of entries like this:

      ...
      
      THREAD START (obj=35c44e0, id = 60, name="JMS SessionPool Worker-0", group="ASF Session Pool Threads")
      THREAD START (obj=35bf1d0, id = 61, name="JMS SessionPool Worker-1", group="ASF Session Pool Threads")
      THREAD START (obj=35bc0b8, id = 62, name="JMS SessionPool Worker-2", group="ASF Session Pool Threads")
      THREAD START (obj=33c2658, id = 63, name="JMS SessionPool Worker-3", group="ASF Session Pool Threads")
      THREAD START (obj=33bdfb0, id = 64, name="JMS SessionPool Worker-4", group="ASF Session Pool Threads")
      THREAD START (obj=34ff420, id = 65, name="JMS SessionPool Worker-5", group="ASF Session Pool Threads")
      THREAD START (obj=34f4ba0, id = 66, name="JMS SessionPool Worker-6", group="ASF Session Pool Threads")
      THREAD START (obj=34e3408, id = 67, name="JMS SessionPool Worker-7", group="ASF Session Pool Threads")
      THREAD START (obj=33a0708, id = 68, name="JMS SessionPool Worker-8", group="ASF Session Pool Threads")
      THREAD START (obj=339bb60, id = 69, name="JMS SessionPool Worker-9", group="ASF Session Pool Threads")
      THREAD START (obj=33dc438, id = 70, name="JMS SessionPool Worker-10", group="ASF Session Pool Threads")
      THREAD START (obj=33d6558, id = 71, name="JMS SessionPool
      
      ...
      


      The number of JMS SessionPool threads being initiated (and not closed) leads me to believe that JBossMQ is creating more threads per message queue than my Java memory settings will permit. (I currently have the server running with the default heap floor/ceiling of 128MB/128MB: -Xms128m -Xmx128m.)' Though I might be able to fix the problem by increasing the maximum heap size, it does not seem that this would guarantee that no further OutOfMemoryErrors would occur.

      My questions are:

      1. Does this seem a reasonable / accurate assessment of the problem?

      2. If so, is there any way to limit the number of MDB threads which JBoss spawns to handle each message queue?

      Thanks in advance. Please let me know if I have failed to give enough information.

        • 1. Re: Too many threads for message queue?
          sumitsu

          For anyone else who might be having this problem: I think I have figured it out.

          My initial conclusion was correct; JBoss was creating more message threads than it had the heap capacity to support, causing an OutOfMemoryError. The minimum and maximum number of message threads for a standard MDB queue is regulated by the message-driven-bean invoker-proxy-binding in conf/standardjboss.xml:

          <invoker-proxy-bindings>
           <invoker-proxy-binding>
           <name>message-driven-bean</name>
          ...
           <MinimumSize>1</MinimumSize>
           <MaximumSize>15</MaximumSize>
          ...
          


          You can change the default values, or specify custom minimum/maximum number of threads for the MDB(s) in your app by doing the following:

          1. Copy the "message-driven-bean" invoker-proxy-binding from standardjboss.xml into the jboss.xml for your application. Remember to enclose it in <invoker-proxy-bindings> tags.

          2. Change the name tag to something else.

          3. Copy the "Standard Message Driven Bean" container-configuration into your application's jboss.xml. It should look something like this:

          <container-configuration>
           <container-name>Standard Message Driven Bean</container-name>
           <call-logging>false</call-logging>
           <invoker-proxy-binding-name>message-driven-bean</invoker-proxy-binding-name>
          ...
          <container-configuration>
          


          Remember to enclose it in <container-configurations> tags.

          4. Change the container-name tag value to something else.

          5. Change the invoker-proxy-binding-name tag to reflect the new name of your invoker-proxy-binding.

          6. Make sure that all the MDB references in jboss.xml refer to the new container configuration by changing/adding the configuration-name tag:

          <enterprise-beans>
           <message-driven>
           <ejb-name>SomeMDB</ejb-name>
           <destination-jndi-name>queue/SomeMDBQueue</destination-jndi-name>
           <configuration-name>WhateverNameYouGaveTheContainerConfig</configuration-name>
           </message-driven>
          
          ...
          


          I think that the process is similar for stateless session beans as well, but might require some research as to how it differs.

          Relevant links:

          http://wiki.jboss.org/wiki/Wiki.jsp?page=ConfigJBossMDB
          http://www.precisejava.com/javaperf/j2ee/EJB.htm#EJB148

          • 2. Re: Too many threads for message queue?
            sumitsu

            The formatting may make it unclear, so note that where I say "Remember to enclose in ...", the formats should be, respectively:

            <invoker-proxy-bindings>
             <invoker-proxy-binding>
             ....
             </invoker-proxy-binding>
            </invoker-proxy-bindings>
            


            and

            <container-configurations>
             <container-configuration>
             ....
             </container-configuration>
            </container-configurations>