我的 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/