【发布时间】:2013-08-01 00:38:37
【问题描述】:
我写了简单的 NIO 服务器:
public static void main(String[] args) throws Exception
{
ByteBuffer buffer = ByteBuffer.allocateDirect(65536);
Selector selector = Selector.open();
ServerSocketChannel server = ServerSocketChannel.open();
server.configureBlocking(false);
server.bind(new InetSocketAddress(724));
server.register(selector, SelectionKey.OP_ACCEPT);
while(server.isOpen())
{
selector.selectNow();
Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
while(iterator.hasNext())
{
SelectionKey key = iterator.next();
iterator.remove();
if(!key.isValid())
{
System.out.println("Invalid key removed!");
key.channel().close();
key.cancel();
continue;
}
if(key.isAcceptable())
{
server.accept().configureBlocking(false).register(selector, SelectionKey.OP_READ);
System.out.println("Accepting channel...");
continue;
}
if(key.isReadable())
{
SocketChannel channel = (SocketChannel) key.channel();
try
{
channel.read((ByteBuffer) buffer.clear());
if(buffer.flip().limit() == 0)
{
continue;
}
System.out.println(buffer.get() & 0xFF);
} catch(Exception e)
{
e.printStackTrace();
channel.close();
key.cancel();
}
}
}
}
}
它是客户:
public static void main(String[] args) throws Exception
{
try(Socket socket = new Socket("localhost", 724))
{
OutputStream output = socket.getOutputStream();
output.write(15);
output.flush();
}
}
一旦客户端与服务器断开连接,CPU 的负载会增加高达 40%
我试图找到解决方案,但搜索没有给出任何结果。 我认为这是由于选择器没有删除断开客户端的事实,但我不知道如何测试 - 客户端是否断开连接。 channel.isOpen() 总是返回 true。
【问题讨论】:
-
您是否尝试过使用VisualVM 进行分析?这可能会准确地告诉您系统将时间花在哪里。
-
编辑:大部分 CPU 时间花在 java.net.SocketInputStream.read(byte[], int, int);
-
刚刚关闭频道的用户不需要取消key。
标签: java asynchronous cpu nio memory-leaks