简体   繁体   English

如何破坏SelectionKey附件? attach(null)不起作用

[英]How destroy SelectionKey attachment? attach(null) doesn't work

My java application has memory leaks - when my resources clearing code is executing task manager shows that memory usage wasn't changed. 我的java应用程序有内存泄漏 - 当我的资源清除代码正在执行时,任务管理器显示内存使用情况没有改变。 My code 我的代码

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();
      }
    }

Testing logic - I wrote simple TCP client java programm sending 100 messages to server. 测试逻辑 - 我写了简单的TCP客户端java程序向服务器发送100条消息。 I intentionally allocated large buffer - 1MB for each connection. 我故意为每个连接分配大缓冲区 - 1MB。 When client finishes his job int x = sc.read(bb); 当客户完成他的工作时int x = sc.read(bb); returns -1 and the following code is executed: 返回-1并执行以下代码:

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

I checked it with debug output, this code was really executed but task manager still showes large memory usage. 我用调试输出检查了它,这段代码真的被执行但是任务管理器仍然显示大量内存使用。 where is the problem? 问题出在哪儿?

Certainly key.attach(null) works. 当然key.attach(null)有效。 If it didn't, attaching a non-null object wouldn't work either. 如果没有,附加非null对象也不起作用。 Same code. 相同的代码。

But, in any case, closing the SocketChannel cancels the key, which removes it from all key sets of all Selectors it was registered with, so you will never see the key again anyway, so it becomes eligible for GC, and so does the attachment, regardless of whether you call key.attach(null) or not, which is therefore redundant. 但是,在任何情况下,关闭SocketChannel取消密钥,从而将密钥从注册的所有Selectors所有密钥集中删除,因此您无论如何都不会再次看到密钥,因此它符合GC的条件,附件也是如此,无论你是否调用key.attach(null) ,这都是多余的。 Either you have another reference to your attachment somewhere else, or your memory usage problem is elsewhere. 您可能在其他地方有另一个对附件的引用,或者您的内存使用问题在其他地方。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM