![](/img/trans.png)
[英]Java.nio.channels.ServerSocketChannel - accept() memory leak
[英]java.nio.channels.ServerSocketChannel not closing properly
我有一個java.nio.channels.ServerSocketChannel
,其初始化如下:
while(true)
{
ServerSocketChannel channel = ServerSocketChannel.open();
InetSocketAddress serverSocket = new InetSocketAddress(host,port);
channel.bind(serverSocket);
SocketChannel ch = channel.accept();
// Later on when I have read off data from a client, I want to shut this
// connection down and restart listening.
channel.socket().close(); //Just trying to close the associated socket
// too because earlier approaches failed
channel.close();
}
當我從客戶端發送第一條消息時,它已成功傳遞到服務器,並且客戶端程序退出 。 然后麻煩開始了。 當我再次初始化客戶端並嘗試建立與第一次相同的服務器端口和地址時,
java.net.BindException:地址已在使用中:connect
即使我關閉了關聯的通道/套接字也是如此。 我一直在更新ServerSocketChannel
和InetSocketAddress
對象,因為在寫入之后我的客戶端實例必須關閉,因此我必須脫離該通道,並且由於關閉該通道后無法重用該通道,因此每次都必須創建一個新對象。 我的理論是,由於每次都重新分配channel
引用,孤立的對象變成GC的主角,但是由於close()方法顯然無法正常工作,通道仍然有效,直到GC收集到我的端口為止。 盡管如此,我還是嘗試在while循環之前保留ServerSocketChannel
和InetSocketAddress
對象的初始化,但這並沒有幫助,並且第一次寫入后發生了與以前相同的異常。
ServerSocketChannel channel = ServerSocketChannel.open();
InetSocketAddress serverSocket = new InetSocketAddress(host,port);
channel.bind(serverSocket);
while (true)
{
SocketChannel ch = channel.accept();
//read from a client
}
為了清楚起見,這是我如何從客戶端進行連接:
SocketChannel ch=SocketChannel.open();
ch.bind(new InetSocketAddress("localhost", 8077));
InetSocketAddress address=new InetSocketAddress("localhost",8079);
//the address and port of the server
System.out.print(ch.connect(address));
ByteBuffer buf=ByteBuffer.allocate(48);
buf.clear();
buf.put("Hellooooooooooooooooooooooooo".getBytes());
buf.flip();
while(buf.hasRemaining()) {
ch.write(buf);
}
ch.close();
這樣做可能也會有所幫助:
channel.setOption(StandardSocketOptions.SO_REUSEADDR,true);
搜索有關此選項的信息以了解更多信息。
還要執行ch.close()來GC客戶端套接字。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.