B4J Question [RESOLVED] B4J - Server, WebSockets, MAP, Threads not being cleared - VisualVM being used to Monitor

Jmu5667

Well-Known Member
Licensed User
Longtime User
Hi all

I have previously been successful with creating a Web-socket server which managed the creation on web-sockets and seeing the threads being destroyed in Visual VM.

The current project is quite similar except that each web-socket connection is being added to a thread safe map, and when the connection is no longer valid, either the user closed the connection or it was not serviced (did not receive a ping from the client), it is removed from the map. This all appears to be be working except when I look at the thread handling in Visual VM, the threads are not being destroyed.

The basic structure is based on Erel's Web Chat, where there is a shared code module that handles the insertion and removal from the map.

Does anyone have any insights into this. In my previous project Erel explained that the thread is destroyed when there are no live references left, so there is no need for a class destruct method like in .NET etc.

Regards

John.
 

Jmu5667

Well-Known Member
Licensed User
Longtime User
Have you let it run for a few days? Are you sure that the threads are not being killed eventually? It can be tricky.
Hi Erel

I let it run over the weekend and the threads as still there. The shared module is :

B4X:
Sub Process_Globals
   
   Public connections As Map ' actual web socket connections, key is IMEI of device
   Public connHelper As Map  ' web socket id, Key is IMEI of device, and the a type to hold the last ping date/time of the device
   
End Sub

Public Sub Init
   
   'this map is accessed from other threads so it needs to be a thread safe map
   connections = Main.srvr.CreateThreadSafeMap
   connHelper = Main.srvr.CreateThreadSafeMap
   
End Sub

Public Sub NewConnection(c As tcp_client, name As String)
   
   connections.Put(name, c)   
   Log("TCP SHARED " & DateTime.Time(DateTime.Now) & " - NEW CONNECTION " & name)
   
End Sub

Public Sub NewPing(tc As Connection, name As String)
   
   connHelper.Put(name, tc)
   Log("TCP SHARED " & DateTime.Time(DateTime.Now) & " - NEW PING " & tc.imei)
   
End Sub

Public Sub NewMessage(Name As String, msg As String)
   'notify each of the connected users about the new message
   For Each c As tcp_client In connections.Values
       CallSubDelayed2(c, "sendMessage", msg)
   Next
End Sub

Public Sub Disconnect(c As tcp_client, name As String)
   
   Log("TCP SHARED " & DateTime.Time(DateTime.Now) & " - CURRENT CONNECTIONS " & connections.Size )
   Log("TCP SHARED " & DateTime.Time(DateTime.Now) & " - DISCONNECT CONNECTION " & name)
   Log(connections.Remove(name))
   Log(connHelper.Remove(name))
   Log("TCP SHARED " & DateTime.Time(DateTime.Now) & " - REMAINING CONNECTIONS " & connections.Size )
   
End Sub

The log data of the disconnect is :

B4X:
TCP SHARED 13:26:10.782 - CURRENT CONNECTIONS 1
TCP SHARED 13:26:10.782 - DISCONNECT CONNECTION 587343134272233
[ws=anywheresoftware.b4j.object.WebSocket@bf3bbf, msg=, c=[IsInitialized=true, imei=587343134272233, last_ping=1531743997043
, threadName=pool-1-thread-6]
, main=null, mod_udt=null, tcp_shared=null
]
[IsInitialized=true, imei=587343134272233, last_ping=1531743997043
, threadName=pool-1-thread-6]
TCP SHARED 13:26:10.782 - REMAINING CONNECTIONS 0

I am currently looking to trying the kill the thread some inline java.

Regards

John.
 
Upvote 0

Jmu5667

Well-Known Member
Licensed User
Longtime User
Upvote 0

Jmu5667

Well-Known Member
Licensed User
Longtime User
This is not related.
ok

How many threads do you see in the monitoring tool?

A couple of things so I don't waste your time.

1. Current Java:
JVM: Java HotSpot(TM) Client VM (25.152-b16, mixed mode)
Java: version 1.8.0_152, vendor Oracle Corporation
Java Home: C:\Program Files (x86)\Java\jdk1.8.0_152\jre

2. I have a B4J UI to test all of this. So I just keep loading new B4J UI to simulate B4A users. I have just noticed if I load a single UI app, connect and disconnect(keep doing this), thread are created up to 10 and no more, and it (JAVA) seems to keep a pool a threads and it seems recycle them. Is this possible ?

3. I will spend the rest of the day testing this and let you know the results.

Regards

J.
 
Upvote 0

Jmu5667

Well-Known Member
Licensed User
Longtime User
So, the test I have just started had 14 open connections. I closed the 14th and will wait and see what happens.

Log Data:
B4X:
2018-07-16 14:43:50.093:INFO::main: Logging initialized @160ms to org.eclipse.jetty.util.log.StdErrLog
2018-07-16 14:43:50.242:INFO:oejs.Server:main: jetty-9.4.z-SNAPSHOT; built: 2018-05-03T15:56:21.710Z; git: daa59876e6f384329b122929e70a80934569428c; jvm 1.8.0_152-b16
2018-07-16 14:43:50.288:INFO:oejs.session:main: DefaultSessionIdManager workerName=node0
2018-07-16 14:43:50.288:INFO:oejs.session:main: No SessionScavenger set, using defaults
2018-07-16 14:43:50.290:INFO:oejs.session:main: node0 Scavenging every 600000ms
2018-07-16 14:43:50.316:INFO:oejsh.ContextHandler:main: Started o.e.j.s.ServletContextHandler@1deb50e{/,file:///C:/Users/John%20Murphy/Documents/B4J/Isle%20Systems/ptt%20ptx/Objects/www,AVAILABLE}
2018-07-16 14:43:50.320:INFO:oejs.AbstractNCSARequestLog:main: Opened C:\Users\John Murphy\Documents\B4J\Isle Systems\ptt ptx\Objects\logs\b4j-2018_07_16.request.log
2018-07-16 14:43:50.747:INFO:oejs.AbstractConnector:main: Started ServerConnector@1bbe1b6{HTTP/1.1,[http/1.1]}{0.0.0.0:17002}
2018-07-16 14:43:50.748:INFO:oejs.Server:main: Started @815ms
TCP CLIENT 14:44:00.626 - THREAD NAME pool-1-thread-1
TCP SHARED 14:44:00.641 - NEW CONNECTION 862435726087865
TCP CLIENT 14:44:07.425 - THREAD NAME pool-1-thread-2
TCP SHARED 14:44:07.427 - NEW CONNECTION 787771384455840
TCP CLIENT 14:44:12.183 - THREAD NAME pool-1-thread-3
TCP SHARED 14:44:12.185 - NEW CONNECTION 654776660107826
TCP CLIENT 14:44:14.610 - THREAD NAME pool-1-thread-4
TCP SHARED 14:44:14.617 - NEW CONNECTION 366505718870631
TCP CLIENT 14:44:17.447 - THREAD NAME pool-1-thread-5
TCP SHARED 14:44:17.450 - NEW CONNECTION 722677144738662
TCP CLIENT 14:44:20.475 - THREAD NAME pool-1-thread-6
TCP SHARED 14:44:20.476 - NEW CONNECTION 655045011681566
TCP CLIENT 14:44:22.652 - THREAD NAME pool-1-thread-7
TCP SHARED 14:44:22.654 - NEW CONNECTION 053620654747711
TCP CLIENT 14:44:25.027 - THREAD NAME pool-1-thread-8
TCP SHARED 14:44:25.029 - NEW CONNECTION 802742077138226
TCP CLIENT 14:44:27.762 - THREAD NAME pool-1-thread-9
TCP SHARED 14:44:27.764 - NEW CONNECTION 873586280430648
TCP CLIENT 14:44:32.816 - THREAD NAME pool-1-thread-10
TCP SHARED 14:44:32.819 - NEW CONNECTION 481153688216885
TCP CLIENT 14:44:38.121 - THREAD NAME pool-1-thread-11
TCP SHARED 14:44:38.122 - NEW CONNECTION 626316633842322
TCP CLIENT 14:45:19.079 - THREAD NAME pool-1-thread-12
TCP SHARED 14:45:19.110 - NEW CONNECTION 533757646502615
TCP CLIENT 14:45:27.902 - THREAD NAME pool-1-thread-13
TCP SHARED 14:45:27.932 - NEW CONNECTION 481678385202876
TCP CLIENT 14:45:41.384 - THREAD NAME pool-1-thread-14
TCP SHARED 14:45:41.424 - NEW CONNECTION 728485848051785
TCP CLIENT 14:46:01.157 - SOCKET DISCONNECT 728485848051785
TCP SHARED 14:46:01.157 - CURRENT CONNECTIONS 14
TCP SHARED 14:46:01.157 - DISCONNECT CONNECTION 728485848051785
[vvv2=anywheresoftware.b4j.object.WebSocket@1993335, vvv3=, vvv4=[IsInitialized=true, imei=728485848051785, last_ping=1531748867260
, threadName=pool-1-thread-14]
, vv6=null, mod_udt=null, tcp_shared=null
]
[IsInitialized=true, imei=728485848051785, last_ping=1531748867260
, threadName=pool-1-thread-14]
TCP SHARED 14:46:01.158 - REMAINING CONNECTIONS 13

VM thread inspector on thread 14 which I closed:

B4X:
2018-07-16 14:47:29

"pool-1-thread-14" - Thread t@38
   java.lang.Thread.State: TIMED_WAITING
   at sun.misc.Unsafe.park(Native Method)
   - parking to wait for <17f59e7> (a java.util.concurrent.SynchronousQueue$TransferStack)
   at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
   at java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:460)
   at java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:362)
   at java.util.concurrent.SynchronousQueue.poll(SynchronousQueue.java:941)
   at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1073)
   at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
   at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
   at java.lang.Thread.run(Thread.java:748)

   Locked ownable synchronizers:
   - None

At 5 pm this evening I will close all the connections and see what it is like in the morning.
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
Of course. The server maintains all kinds of pools of threads.

Unless you see hundred or more threads then everything is fine.
 
Upvote 0

Jmu5667

Well-Known Member
Licensed User
Longtime User
The test I ran have 14 connections, closed 4, 4 threads closed, closed the other 10, 10 threads kept alive, all is good. Left is running overnight and the thread pool is still at 10.

Thanks.

John.
 
Upvote 0
Cookies are required to use this site. You must accept them to continue using the site. Learn more…