简体   繁体   中英

Memory leak in a multithreaded Java web server

I have a multithreaded Java web server that accepts requests from clients.

Each request in the RAM allocates memory for this request, but it is not cleared after the socket is closed. Cleanup occurs only after the web server is restarted.

If it is a memory leak, then in which part of the code can it occur?

My code:

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();
            }
        }
    }
}

Starting a new thread for every incoming connection is INCREDIBLY inefficient and is probably what is leaking memory.

The correct approach is to use a thread pool with a fixed number of threads that are reused.

It's also worth pointing out that threads consume large amounts of native memory (off the Java heap) and very little on heap memory, so will not trigger garbage collection which in turn will call the finalizer to free up the native side.

EDIT: Also the code doesn't do what you think it does. Having the accept outside the loop means that the code will just spin up threads for the same connection over and over agian, not a new thread for each connection.

Creating threads in while(true) loop is never a good idea.
By default, each Thread created will allocate; 1mb for 64 bit jvm and 128 kb for 32 bit jvm for its stack (this is for linux os, other details here ). Try ExecutorService for this kind of things. Threads are valuable resources.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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