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