Pitfall in creating multiple ORBs in VisiBroker for Java




VisiBroker for Java aka VBJ allows developers to create multiple ORBs in a CORBA application. Each ORB creates its own resources in the memory. So, the developers should understand that if more than one ORB is created without understanding the implication, the resources can add up and the application will eventually run out of memory. This article explains the resources created for each ORB and identifies which resources will add up in the memory when there are multiple ORBs in a VBJ application. 

ORB Resources explained

In a VBJ application, when an ORB is initialized with an osagent enabled, the below threads are created. There are other threads created as well but our focus is going to be only on these threads. The "AreYouAlive" and "DatagramThread" threads are created for the communication with osagent. These two threads will not be created when osagent communication is disabled in an application. The "GarbageCollector" is created to garbage collect the resources such as worker threads(which processes the incoming CORBA requests), connections, etc.

"AreYouAlive orb=16e1fb1" daemon prio=6 tid=0x194c1000 nid=0xbe0 in Object.wait() [0x1a11f000] java.lang.Thread.State: TIMED_WAITING (on object monitor)
  at java.lang.Object.wait(Native Method)
- waiting on <0x048f7e40> (a com.inprise.vbroker.ds.DSUser$AreYouAlive)
  at com.inprise.vbroker.ds.DSUser$AreYouAlive.run(Unknown Source)
  - locked <0x048f7e40> (a com.inprise.vbroker.ds.DSUser$AreYouAlive)
"DatagramThread orb=16e1fb1" daemon prio=6 tid=0x194be800 nid=0x7fc runnable [0x19fdf000] java.lang.Thread.State: RUNNABLE
at java.net.PlainDatagramSocketImpl.receive0(Native Method)
- locked <0x048f7a38> (a java.net.PlainDatagramSocketImpl)
at java.net.PlainDatagramSocketImpl.receive(PlainDatagramSocketImpl.
- locked <0x048f7a38> (a java.net.PlainDatagramSocketImpl)
at java.net.DatagramSocket.receive(DatagramSocket.java:725)
- locked <0x04906cc8> (a java.net.DatagramPacket)
- locked <0x048f79f8> (a java.net.DatagramSocket)
at com.inprise.vbroker.ds.DSUser$DatagramThread.run(Unknown Source)
"GarbageCollector orb=16e1fb1" daemon prio=6 tid=0x194d8c00 nid=0x1644 in Object.wait() [0x19e9f000] java.lang.Thread.State: TIMED_WAITING (on obj
ect monitor)
at java.lang.Object.wait(Native Method)
  - waiting on <0x04d42320> (a com.inprise.vbroker.orb.GarbageCollector)
  at com.inprise.vbroker.orb.GarbageCollector.run(Unknown Source)
  - locked <0x04d42320> (a com.inprise.vbroker.orb.GarbageCollector)

If an ORB is resolving "RootPOA" to create child POAs or for performing any POA related functionalities, then an additional "SocketListener" thread and a server socket will be created. If a servant is activated in the "RootPOA", then the clients will connect to this socket to send CORBA requests.

"SocketListener se=iiop_tp scm=iiop_tp orb=922804" daemon prio=6 tid=0x02590400 nid=0x21fc runnable [0x1a1af000] java.lang.Thread.State: RUNNABLE
  at java.net.PlainSocketImpl.socketAccept(Native Method)
  at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:408)
  - locked <0x04a453b0> (a java.net.SocksSocketImpl)
  at java.net.ServerSocket.implAccept(ServerSocket.java:462)
  at java.net.ServerSocket.accept(ServerSocket.java:430)
  at com.inprise.vbroker.IIOP.Listener.accept(Unknown Source)
  at com.inprise.vbroker.orb.SocketSCM$ListenerThread.run(Unknown Source)
  at java.lang.Thread.run(Thread.java:662)    

Multiple ORBs pitfall explained

The following are the scenarios created to illustrate single and multiple ORBs threads creation and the pitfall associated to it. The test cases created for the following scenarios just create ORB(s) and resolve RootPOA. They do not create child POA or activate any servant in it. If you are creating such POAs and servants, then the number of threads will differ for each ORB as explained above in ORB Resources section.

Please note that for all the scenarios tested, the VisiBroker version used is 8.5, jdk is 1.6, OS is Solaris 10 Sparc. An osagent should be running as well before starting the tests. To generate thread dumps, you can use either jstack tool or "kill -3 <pid_of_server>". In the scenarios tested, I used "kill -3 <pid_of_server>" which sends the thread dumps to the standard output. I used vbjc and vbj tools provided in the VisiBroker installation for compiling and running the test cases.

The test cases used for testing these scenarios can be downloaded here.

Scenario 1

Single ORB creation with osagent enabled

1. Start VBJ Server

     - vbj SingleORB_Server

2. Generate the thread dump 

     - kill -3 <pid_of_server>(or use jstack tool)

When an ORB is created with osagent enabled and if it also resolves RootPOA, you will see "AreYouAlive", "DatagramThread", "GarbageCollector", "SocketListener" and other threads. Here "AreYouAlive" and "DatagramThread" threads are created only when an osagent is enabled.

Scenario 2

Single ORB creation with osagent disabled

1. Start VBJ Server

     - vbj -Dvbroker.agent.enableLocator=false SingleORB_Server

2. Generate the thread dump

     - kill -3 <pid_of_server>(or use jstack tool)

In this scenario, you will see "GarbageCollector" and "SocketListener" threads but not "AreYouAlive" and "DatagramThread" as osagent is disabled using "vbroker.agent.enableLocator=false" property.

Multiple ORBs creation with osagent enabled

1. Start VBJ Server

     - vbj MultipleORBs_Server

2. Generate the thread dump

     - kill -3 <pid_of_server>(or use jstack tool)

This example is just trying to illustrate what would happen when the application creates multiple ORB instances without understanding the impact. In this scenario, by default, twenty ORBs are created with osagent enabled. Each ORB also resolves RootPOA. So, you will see twenty "AreYouAlive", "DatagramThread", "GarbageCollector" and "SocketListener" threads and a server socket for each ORB. When there are multiple ORBs(say in 100s) with each resolving RootPOA created without knowing the consequences, there will be huge number of threads and server sockets created and eventually the JVM will run out of memory.

Scenario 4

Multiple ORBs creation with osagent disabled

1. Start VBJ Server

     - vbj -Dvbroker.agent.enableLocator=false MultipleORBs_Server

2. Generate the thread dump

     - kill -3 <pid_of_server>(or use jstack tool)

In this scenario, you will see twenty(default) "GarbageCollector" and "SocketListener" threads as the osagent is disabled. When there are multiple ORBs(say in 100s) created without knowing the impact, there will be quite a lot of threads created and eventually the JVM might run out of memory.

In conclusion, the developers should analyse and understand their requirement and also the implication of creating multiple ORB(s) explained in this article before creating them in their VBJ application.

One solution to avoid creating multiple ORB(s) would be, the application can create a static singleton method such as getORB(). This method will then create a static ORB instance when the reference is null otherwise return the same ORB instance. Then, the application needs to invoke this getORB() method whenever an ORB instance is needed. This solution will make sure that there is one ORB instance used across the application. This solution also has been illustrated in the MultipleORBs_Server example which can be downloaded here.

Please do note that VBJ returns a new ORB instance for each org.omg.CORBA.ORB.init(..) call. However, VisiBroker for C aka VBC returns the same ORB instance for every CORBA::ORB_init(..) call and does not allow creation of multiple ORBs using it. Thus, you do not have the above mentioned issues in VBC.




How To-Best Practice
Comment List
Related Discussions