简体   繁体   中英

Java.nio.channels.ServerSocketChannel - accept() memory leak

I got thread for server in my Android app and need to handle it properly when user decide to close it. I choose non-blocking ServerSocketChannel which accept() clients.
And got this 问题

public class SocketServer extends Thread
{
  private static final String LOG_TAG  = "SocketServer";
  private boolean isRunning  = false;
  private ServerSocketChannel listener = null;

public void _stop()
{
  this.isRunning = false;
}

public void _start()
{
  this.isRunning = true;
  this.start();
}

private void free()
{
  try
  {
    listener.close();
  }
  catch (IOException e)
  {
    //Error handle
  }
  listener = null;
}

public SocketServer(int port)
{
  super();
  try
  {
     listener = ServerSocketChannel.open();
     listener.configureBlocking(false);
     listener.socket().bind(new InetSocketAddress(port));
  }
  catch (IOException e)
  {
    //Error handle
  }
}

public void run()
{
  SocketChannel client = null;
  while(isRunning)
  {
    try
    {
      client = listener.accept();//GC going mad
    }
     if(client != null)
                Log.i(LOG_TAG, "ACCEPTED CLIENT");

    catch (IOException e)
    {
      //Error handle
    }
  }
    free();
}  

All i'm doing is accepting new client - getting null because of no incoming connections and do it again until server is stopped.
ServerClient client is null at start and assigned to null by accept() if no connections available.

But Java's garbage collector thinks what client is somehow init by accept() or accept() somehow allocate some memory, which GC cleans after every while loop.
If comment accept() line (eg do nothing) where will be no GC at all, so problem exactly in accept().

This quite not right in my opinion.

PS If there is some way to break blocking ServerSocket accept()/ Socket read() state and exit properly, please tell me.

PS 2 Is it safe to write/ read to SocketChannel socket() as to Socket, will it block thread?

Many operations in Java create temporary objects internally to do their work.

You are much better off using a blocking SocketServer. This way the objects it creates is only on a per-accepted-Socket basis rather than a per-attempt basis.

I suggest you implement blocking NIO with a thread (or two) per connection first. If then you discover you have a performance issue with the number of threads you have, try using a Selector with non-blocking NIO.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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