繁体   English   中英

多线程 Java Web 服务器中的内存泄漏

[英]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.

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