Hi jetty-users,
I would like to see is there a way to resolve this issue: either through coding 
or configuration changes.  Any advice and suggestions will be greatly 
appreciated. I have encountered the memory leak/accumulation issue using a 
JavaScript WebSocket client communicates with a local application Jetty 
WebSocket server (using Jetty's WebSocket JSR356 implementation).  I have tried 
both Jetty 9.3.3.v20150827 and 9.3.5.v20151012 and the memory leak issue can 
both be observed.  Java version is "1.8.0_60".
What I want to achieve is sending files (one at a time as instructed by the 
user) from the Browser JavaScript WebSocket client to the Jetty WebSocket 
server for processing.

Two memory leak/accumulation issues are observed (using Eclipse Memory 
Analyzer) at the Jetty WebSocket server side:   
   - Each unique files sent got cached in an 
org.eclipse.jetty.io.MappedByteBufferPool object.  The cache persists even with 
the client terminated or server timeout the connection/session.  If the client 
keep send different files, eventually the OutOfMemoryError can occurred at the 
Jetty WebSocket server because the MappedByteBufferPool object memory usage 
just keep growing.
   
   - Is there a way to limit the max number of cached entries or totally 
disable the cache in this MappedByteBufferPool object?
   - I also tried adding the -XX:MaxDirectMemorySize=200m jvm option but it the 
MappedByteBufferPool object memory usage is still growing.
   
   - Each new connection/JsrSession is referenced in the 
org.eclipse.jetty.websocket.server.WebSocketServerFactory object even after the 
session is closed.  The last onBinary (OnMessage) ByteBuffer argument is cached 
with the JsrSession.  After several open/close sessions, the memory usage of 
the WebSocketServerFactory object just keep growing.  BTW, the 
WebSocketServerFactory object also have a reference to the MappedByteBufferPool 
object mentioned above.   

   
   - Is there a way to make the WebSocketServerFactory object not to cache the 
all the previous closed JsrSession objects? 


Below are excerpted (with simplification) from both client and server sides:

================================================================================
 
JavaScript WebSocket client 
side:=============================================function sendFile(file) {    
var reader = new FileReader();    reader.readAsArrayBuffer(file);    
reader.onload = function() {        // this websocket object has been setup 
somewhere else in advance with binaryType = "blob"        
websocket.send(reader.result);    }} Jetty WebSocket server 
side:======================================WSServer.java
-------------
package mytestapp;
import javax.websocket.server.ServerContainer;import 
org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;import 
org.eclipse.jetty.servlet.ServletContextHandler;import 
org.eclipse.jetty.websocket.jsr356.server.deploy.WebSocketServerContainerInitializer;
public class WSServer {
    public static void main(String[] args) {        Server server = new 
Server();
        // Connector        ServerConnector connector = new 
ServerConnector(server);        connector.setPort(8080);
        ServletContextHandler ctx = new 
ServletContextHandler(ServletContextHandler.SESSIONS);        
ctx.setContextPath("/");
        server.setHandler(ctx);        server.addConnector(connector);
        try {            // Initialize javax.websocket layer            
ServerContainer wscontainer = 
WebSocketServerContainerInitializer.configureContext(ctx);
            // Add WebSocket endpoint to javax.websocket layer            
wscontainer.addEndpoint(WSEndpoint.class);            
wscontainer.setDefaultMaxSessionIdleTimeout(0);            
wscontainer.setDefaultMaxTextMessageBufferSize(Integer.MAX_VALUE);            
wscontainer.setDefaultMaxBinaryMessageBufferSize(Integer.MAX_VALUE);
            server.start();            server.join();        } catch (Throwable 
t) {            t.printStackTrace(System.err);        }    }}

WSEndpoint.java---------------
package mytestapp;
import java.io.IOException;import java.nio.ByteBuffer;import 
javax.websocket.OnClose;import javax.websocket.OnError;import 
javax.websocket.OnMessage;import javax.websocket.OnOpen;import 
javax.websocket.Session;import javax.websocket.server.ServerEndpoint;
@ServerEndpoint("/")public class WSEndpoint {
    @OnOpen    public void onOpen(Session session) throws IOException {        
System.out.println("onOpen");    }

    @OnMessage    public void onText(String message, Session session) {        
System.out.println("onText");    }

    @OnMessage    public void onBinary(ByteBuffer bb, Session session) {        
System.out.println("Got binary message, do nothing to make sure there is no 
reference to ByteBuffer and Session");    }
    @OnError    public void onError(Throwable t) {        
System.out.println("Received error: " + t.getMessage());    }
    @OnClose    public void onClose(Session session) {        
System.out.println("onClose");    }}
================================================================================
 

Thanks,Mike
_______________________________________________
jetty-users mailing list
[email protected]
To change your delivery options, retrieve your password, or unsubscribe from 
this list, visit
https://dev.eclipse.org/mailman/listinfo/jetty-users

Reply via email to