java - 如何销毁SelectionKey附件?附加(空)不起作用

标签 java tcp memory-leaks nio

我的 java 应用程序存在内存泄漏 - 当我的资源清除代码正在执行任务管理器时显示内存使用情况没有更改。我的代码

while (isRunning) {
      try 
      {

             selector.select(); 

             long sum=0;

             Set keys =  selector.selectedKeys();
             Iterator it = keys.iterator(); 
             while(it.hasNext())
             {
                 SelectionKey key = (SelectionKey)it.next();
                 if (key.isReadable())
                 { 
                      SocketChannel sc = (SocketChannel) key.channel();

                      ByteBuffer bb;
                      if(key.attachment()==null)
                      {
                          bb = ByteBuffer.allocate(1024*1024);
                          key.attach(bb);
                      }
                      else
                      {
                          bb = (ByteBuffer)key.attachment();
                          bb.clear();
                      }

                      int x =  sc.read(bb); 

                       System.out.println(x +" bytes were read");
                       if(x==-1)
                       {
                           key.attach(null); //doesn't work
                           sc.close();
                           //bb = null; // also doesn't work
                       }
                 } 
             }
           keys.clear();
      } 
      catch (Exception ex) 
      {     
          ex.printStackTrace(new PrintStream(System.out));
      }
      finally
      { 
            //stopServer();
      }
    }

测试逻辑 - 我编写了简单的 TCP 客户端 java 程序,向服务器发送 100 条消息。我特意为每个连接分配了大缓冲区 - 1MB。当客户端完成工作时 int x = sc.read(bb); 返回 -1 并执行以下代码:

if(x==-1)
                           {
                               key.attach(null); //doesn't work
                               sc.close();
                               //bb = null; // also doesn't work
                           }

我用调试输出检查了它,这段代码确实被执行了,但任务管理器仍然显示大量内存使用。问题出在哪里?

最佳答案

当然key.attach(null)作品。如果没有,附加非空对象也不起作用。相同的代码。

但是,无论如何,关闭SocketChannel取消 key ,这会将其从所有 Selectors 的所有 key 集中删除它已注册,因此您将永远不会再看到该 key ,因此它有资格进行 GC,附件也是如此,无论您是否调用 key.attach(null)或不,因此这是多余的。要么您在其他地方有另一个对附件的引用,要么您的内存使用问题在其他地方。

关于java - 如何销毁SelectionKey附件?附加(空)不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17652172/

相关文章:

Python tcp 套接字客户端

linux-kernel - 相同数据包的 TCP 重传,但具有不同的 TCP 负载

haskell - 为什么包装 Data.Binary.Put monad 会导致内存泄漏? (第2部分)

c++内存管理局部变量的内存分配

java - 从 Eclipse 运行 Struts2 应用程序时出现不同的错误

java - Oracle Database 11g 如何通过 HTTPS TLS1.1、TLS1.2 连接到 Web 服务

java - 碰撞未在接触监听器中注册? [Libgdx + Box2d]

java - 初始化一个类,将另一个类对象作为成员变量

Java套接字多次写入和读取

perl - 了解开发::泄漏