Java.nio.channels.ServerSocketChannel - accept()内存泄漏

时间:2012-08-03 13:20:26

标签: java android

我在我的Android应用程序中获得了服务器的线程,并且当用户决定关闭它时需要正确处理它。我选择了无阻塞的ServerSocketChannel,它接受()客户端 得到了这个problem

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

我所做的就是接受新客户端 - 因为没有传入连接而获得 null ,并在服务器停止之前再次执行此操作。
ServerClient 客户端在开始时为空,如果没有可用连接,则由accept()分配给 null

但是Java的垃圾收集器认为什么客户端以某种方式通过accept()或者accept()以某种方式分配一些内存,GC在每个while循环之后清理。
如果注释accept()行(例如什么也不做)那么根本就没有GC,所以在accept()中完全出问题。

在我看来这是不对的。

PS 如果有某种方法可以打破阻止 ServerSocket 接受()/ 套接字读取()状态并正常退出,请告诉我

P.S。 2 写入/读取SocketChannel socket()对Socket是否安全,是否会阻塞线程?

1 个答案:

答案 0 :(得分:1)

Java中的许多操作都在内部创建临时对象来完成他们的工作。

使用阻塞SocketServer会好得多。这样,它创建的对象仅基于每个接受的套接字而不是基于每次尝试的基础。

我建议你先为每个连接用一个线程(或两个)实现阻塞NIO。如果您发现自己的线程数存在性能问题,请尝试使用具有非阻塞NIO的Selector。