[英]Memory leak in a multithreaded Java web server
我有一个多线程 Java Web 服务器,它接受来自客户端的请求。
RAM中的每个请求都会为这个请求分配内存,但是socket关闭后不会被清除。 仅在重新启动 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();
}
}
}
}
为每个传入连接启动一个新线程的效率非常低,可能是内存泄漏的原因。
正确的方法是使用具有固定数量可重用线程的线程池。
还值得指出的是,线程消耗大量本机内存(在 Java 堆之外),而在堆内存上消耗很少,因此不会触发垃圾收集,而垃圾收集又会调用终结器来释放本机端。
编辑:此外,代码并没有做你认为的那样。 在循环外接受 accept 意味着代码只会一遍又一遍地为同一连接启动线程,而不是为每个连接启动新线程。
在while(true)
循环中创建线程从来都不是一个好主意。
默认情况下,每个创建的线程都会分配; 1mb 用于 64 位 jvm,128 kb 用于 32 位 jvm 的堆栈(这是针对 linux 操作系统,其他详细信息请点击此处)。 为这种事情尝试ExecutorService
。 线程是宝贵的资源。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.