【发布时间】:2015-11-20 16:19:14
【问题描述】:
我正在使用 Jetty 的 JSR356 WebSocket 实现编写一个简单的嵌入式 WebSocket 服务器。我的服务器侦听本地端口,Web 应用程序将创建从浏览器到本地服务器的 WebSocket 连接,并将二进制数据发送到服务器。 这是我的服务器代码示例:
服务器:
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);
}
}
}
服务器端点:
@ServerEndpoint("/")
public class WSEndpoint {
@OnOpen
public void onOpen(Session session) throws IOException {
session.getBasicRemote().sendText("onOpen");
}
@OnMessage
public void onMessage(String message, Session session) {
System.out.println("Received text message: " + message);
}
@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) {
t.printStackTrace();
}
@OnClose
public void onClose(Session session) {
}
}
在本例中,不对传入的二进制字节缓冲区执行任何操作,以避免出于测试目的对该对象的任何引用。
但是在传输了几个文件的一些测试运行之后,这台服务器的内存使用量显着增加,几乎没有下降。即使我断开连接,内存仍然没有关闭,在我不得不停止服务器之前,它最多需要 1.5 GB 的内存。
然后我转储内存,发现我传输的所有二进制文件都被org.eclipse.jetty.io.MappedByteBufferPool对象保存在内存中,并且从未释放过。 IMO,Jetty 会处理这个 MappedByteBufferPool 并在适当的时候释放内存,因为它没有暴露给我们,但似乎缓冲池从未被释放。
所以我的问题是:
- 我的代码做错了吗?
- 如果代码没问题,如何解决这个问题?
谢谢!
【问题讨论】:
标签: java jetty bytebuffer