简体   繁体   English

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

[英]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. 我的Android应用程序中有服务器线程,需要在用户决定关闭它时正确处理它。 I choose non-blocking ServerSocketChannel which accept() clients. 我选择非阻塞的ServerSocketChannel接受()客户端。
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. 我正在做的就是接受新客户端-因为没有传入连接而为null ,然后再次执行直到服务器停止。
ServerClient client is null at start and assigned to null by accept() if no connections available. ServerClient 客户端在启动时为null ,如果没有可用的连接,则由accept()分配为null

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. 但是Java的垃圾收集器认为,什么客户端通过某种方式由accept()或accept()初始化,从而以某种方式分配一些内存,该内存在每次while循环后由GC清除。
If comment accept() line (eg do nothing) where will be no GC at all, so problem exactly in accept(). 如果注释accept()行(例如不执行任何操作)将根本没有GC,那么问题完全在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:如果有某种方法可以打破阻止ServerSocket accept()/ Socket read()状态并正确退出的情况,请告诉我。

PS 2 Is it safe to write/ read to SocketChannel socket() as to Socket, will it block thread? PS 2就套接字而言,对SocketChannel socket()进行写入/读取是否安全,会阻塞线程吗?

Many operations in Java create temporary objects internally to do their work. Java中的许多操作都在内部创建临时对象以完成其工作。

You are much better off using a blocking SocketServer. 使用阻塞的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. 我建议您首先为每个连接使用一个(或两个)线程来实现阻塞NIO。 If then you discover you have a performance issue with the number of threads you have, try using a Selector with non-blocking NIO. 如果然后发现线程数量存在性能问题,请尝试使用具有非阻塞NIO的选择器。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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