我有一个多线程 Java Web 服务器,它接受来自客户端的请求。
RAM中的每个请求都会为此请求分配内存,但在套接字关闭后不会被清除。仅在 Web 服务器重新启动后才会进行清理。
如果是内存泄漏,那么会发生在代码的哪一部分呢?
我的代码:
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class Main {
public static void main(String[] args) {
try (ServerSocket server = new ServerSocket(80)) {
Socket socket = server.accept();
while (true) {
new Thread(new Client(socket)).start();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
class Client implements Runnable {
private Socket socket;
Client(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
try {
System.out.println("run");
} finally {
try {
socket.close();
System.out.println("Socket closed: " + socket);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
最佳答案
为每个传入连接启动一个新线程的效率极低,并且可能是内存泄漏的原因。
正确的方法是使用具有固定数量的可重用线程的线程池。
还值得指出的是,线程消耗大量 native 内存(Java 堆外),而堆内存很少,因此不会触发垃圾收集,垃圾收集反过来会调用终结器来释放 native 端。
编辑: 而且该代码并没有按照您的想法进行操作。将接受放在循环之外意味着代码只会一遍又一遍地为同一连接旋转线程,而不是为每个连接创建一个新线程。
关于java - 多线程 Java Web 服务器中的内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48608426/