java - Jetty WebSocket 服务器不会释放二进制消息字节缓冲池

标签 java jetty bytebuffer

我正在使用 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 并在适当的时候释放内存,因为它没有暴露给我们,但缓冲池似乎从未被释放。

所以我的问题是:

  1. 我的代码是否做错了什么?
  2. 如果代码没问题,如何解决这个问题?

谢谢!

最佳答案

这是 Jetty 中修复的错误 9.3.4.v20151007并在 9.3.5.v20151012 中进一步完善。

相关错误:

  • 错误#478829 : WebsocketSession 未清理/内存泄漏
  • 错误#474936 :WebSocketSession 并不总是从 openSession 中清除

关于java - Jetty WebSocket 服务器不会释放二进制消息字节缓冲池,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33646651/

相关文章:

java - Java 中的向下转型会抛出 ClassCastException

java - 如何检查 netbeans 中的编译器和运行时?

jetty - 是否有适用于 Jetty 的应用程序管理控制台?

spring - 硬限制连接 Spring Boot

Apache Solr : Tomcat or Jetty?

java - 如何将 OutputStream 中的数据放入 ByteBuffer?

java - 为什么在 ByteBuffer 中可以直接分配字节,而不能在 FloatBuffer 中分配 float

c - 如何在 C 中将 wchar_t 转换为 BYTE*

java - 使用Java将Mat复制到OpenCV中的原始数组? (出现 "multiple of channels count"错误)

java - getValue() 方法可以通过两种方式重写。哪一个是正确的?