title: Java memory leak from thread pool
body: <p>I am trying to build a server but the use of a thread pool has introduced a memory leak that causes my heap to over flow.  </p>
  
  <p>My server creates two primary threads from the main thread, the Acceptor and the Consumer. I am new to JProfiler but it seemed to very clearly point me to the below code (the Acceptor) as the culprit.</p>
  
  <p><img src="https://i.stack.imgur.com/xlKT5.png" alt="enter image description here"></p>
  
  <p>The Acceptor thread accepts new connections from clients. Upon an accepted call a new thread from the thread pool is used to handle the connection. </p>
  
  <pre><code>public class AcceptorThread implements Runnable{
  LinkedBlockingQueue&lt;LinkedList&lt;Log_Message&gt;&gt; queue = null;
  public AcceptorThread(LinkedBlockingQueue&lt;LinkedList&lt;Log_Message&gt;&gt; queue){
      this.queue = queue;
  }
  
  @Override
  public void run() {
      ExecutorService acceptors = Executors.newCachedThreadPool();
      ServerSocket socket = null;
      try {
          socket = new ServerSocket(44431);
      } catch (IOException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
      }
      while(!init_LogServer.isStopped()){
          Socket connectionSocket = null;
          try {
              connectionSocket = socket.accept();
          } catch (IOException e) {
              e.printStackTrace();
          }
          init_LogServer.addList();
          System.out.println("Accepted New List: " + init_LogServer.getListCount());
          Runnable worker = new List_Acceptor(connectionSocket, queue);
          acceptors.execute(worker);
      }
  }
  </code></pre>
  
  <p>}</p>
  
  <p>The new thread from the thread pool receives a linked list of objects, this list is added to the queue and the thread is complete. My understanding was that upon completion of the below code the thread would terminate, the below object would be collected by the GC and the thread would re-enter the thread pool for reuse. I can't see any obvious little memory leaks so I'm guessing what happens is that the below class is never collected by the GC causing the heap to build, is that correct? How can I destroy the below object once the received list is added to the queue? </p>
  
  <pre><code>public class List_Acceptor implements Runnable{
  Socket socket = null;
  private LinkedList&lt;Log_Message&gt; lmList = null;
  private LinkedBlockingQueue&lt;LinkedList&lt;Log_Message&gt;&gt; queue = null;
  private String dumpMessage = null;
  
  public List_Acceptor(Socket socket, LinkedBlockingQueue&lt;LinkedList&lt;Log_Message&gt;&gt; queue){
      this.queue = queue;
      this.socket = socket;
  }
  
  @Override
  public void run() {
      ObjectInputStream input = null;
      try {
          input = new ObjectInputStream(socket.getInputStream());
      } catch (IOException e3) {
          // TODO Auto-generated catch block
          e3.printStackTrace();
      }
      Object received = null;
      try {
          received = input.readObject();
      } catch (ClassNotFoundException | IOException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
      }
      try {
          lmList = (LinkedList&lt;Log_Message&gt;) received;
      } catch (Exception e1) {
          //e1.printStackTrace();
          System.out.println("Received DumpLog");
          dumpMessage = (String) received;
          System.out.println("Dump: "+dumpMessage);
          init_LogServer.stop();
          e1.printStackTrace();
      }
  
      //close socket
      try {
          socket.close();
          input.close();
      } catch (IOException e2) {e2.printStackTrace();}
  
      try {
          queue.put(lmList);
      } catch (InterruptedException e) {
          e.printStackTrace();
      }
  
  }
  </code></pre>
  
  <p>}</p>
  
  <p>EDIT: I have learnt that apparently when an object/class is instantiated via a  thread as I do with the thread pool the GC is restricted from cleaning that object. This seems a likely cause for memory leakage and is possibly my problem. With that in mind tomorrow I will redesign so that the AcceptorTread does the necessary steps to put the received list into the queue, it should be slower but will prevent the heap problem. Does that make sense? </p>