gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-01 15:14:41 30 4
gpt4 key购买 nike

我的 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 client 在开始时为 null,如果没有可用的连接,则通过 accept() 分配给 null

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

我认为这完全不对。

P.S.如果有某种方法可以打破阻塞的ServerSocketaccept()/Socketread()状态并正确退出,请告诉我.

附注2 对于Socket来说,对SocketChannel socket()进行写入/读取是否安全,会阻塞线程吗?

最佳答案

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

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

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

关于Java.nio.channels.ServerSocketChannel -accept() 内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11796577/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com