Welcome to the Java Programming Forums


The professional, friendly Java community. 21,500 members and growing!


The Java Programming Forums are a community of Java programmers from all around the World. Our members have a wide range of skills and they all have one thing in common: A passion to learn and code Java. We invite beginner Java programmers right through to Java professionals to post here and share your knowledge. Become a part of the community, help others, expand your knowledge of Java and enjoy talking with like minded people. Registration is quick and best of all free. We look forward to meeting you.


>> REGISTER NOW TO START POSTING


Members have full access to the forums. Advertisements are removed for registered users.

Results 1 to 2 of 2

Thread: Memory Leak in Java executor

  1. #1
    Member
    Join Date
    Nov 2017
    Location
    USA
    Posts
    81
    Thanks
    6
    Thanked 1 Time in 1 Post

    Default Memory Leak in Java executor

    I was surprised to witness the Java Executor behavior – which caused “java.lang.OutOfMemoryError: unable to create new native thread” in our application. I would like to share my surprise (i.e. problem) and resolution to it.

    In order to explain the problem better, I created the following example:
    import java.util.concurrent.ArrayBlockingQueue;
    import java.util.concurrent.ThreadPoolExecutor;
    import java.util.concurrent.TimeUnit;
     
    public class ThreadLeaker {
     
     /**
     * Dummy Job that just prints a statement.
     */
     private class DummyJob implements Runnable {
     
       private String jobName;
     
       public DummyJob(String jobName) {
     
         this.jobName = jobName;
       }
     
       @Override
       public void run() {
     
         System.out.println(this.jobName + " executed!");
       }
     }
     
     public void runJobs() {
     
       // Build an executor with core pool size 5, max pool size 5 and Queue size 5
       ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 5, 60L, TimeUnit.SECONDS,
                                                    new ArrayBlockingQueue<Runnable>(5));
       // Execute 10 jobs;
       for (int counter = 0; counter < 10; ++counter) {
     
         executor.execute(new DummyJob("Dummy Job - " + counter));
       }
     }
     
     public static void main(String args[]) {
     
       new ThreadLeaker().runJobs();
     }
    }
    Above program creates 5 workers threads in the runJobs() method and executes 10 DummyJobs in parallel. In order to do so, it uses ThreadPoolExecutor.

    In the “runJobs()” method, one would expect ThreadPoolExecutor instance & the worker threads created by that executor would be ready for garbage collection when:

    1. “runJobs()” method is completed. As ‘executor’ is a local variable, it should be made available for garbage collection after the execution of the method. As variable has become out of scope.
    2. All jobs that were dropped to the Executor were executed.

    However surprisingly – even though both of the conditions are meet, still worker threads in the ThreadPoolExecutor instance aren’t getting garbage collected. Whenever “runJobs()” method is called, 5 new worker threads gets created and remains in the memory. If “runJobs()” is called few hundred times, several hundreds of worker threads are created. This causes memory leak in the application.

    How to fix this problem?

    On line number 37, one would need to invoke “shutdown()” API. So that all the worker threads would be explicitly destroyed after execution of the jobs. So revised runJobs() method would look like:
    public void runJobs() {
     
      // Build an executor with core pool size 5, max pool size 5 and Queue size 5
      ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 5, 60L, TimeUnit.SECONDS,
                                                   new ArrayBlockingQueue<Runnable>(5));
      // Execute 10 jobs;
      for (int counter = 0; counter < 10; ++counter) {
     
        executor.execute(new DummyJob("Dummy Job - " + counter));
      }
     
      // Explicitly calling shutdown API to destroy threads
      executor.shutdown();
    }

    What triggers this Memory Leak?

    Apparently worker threads were put on to wait state by the Executor. Following is the excerpt from the thread dump of the program. Excerpt shows the stack trace of one of the worker thread in the Executor.

    You can see the line “at java.util.concurrent.locks.LockSupport.park(LockSu pport.java:186)". This will park the threads thus making them not to die down. Only when shutdown() API is invoked it would unpark the threads and they would die down.

    pool-1-thread-5" prio=6 tid=0x0000000007444800 nid=0x33fec waiting on condition
     [0x0000000009eef000]
     java.lang.Thread.State: WAITING (parking)
     at sun.misc.Unsafe.park(Native Method)
     - parking to wait for <0x00000007ac3aff48> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
     at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
     at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2043)
     at java.util.concurrent.ArrayBlockingQueue.take(ArrayBlockingQueue.java:374)
     at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1043)
     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1103)
     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
     at java.lang.Thread.run(Thread.java:722)
     
    Locked ownable synchronizers:
     - None

  2. #2
    Super Moderator Norm's Avatar
    Join Date
    May 2010
    Location
    Eastern Florida
    Posts
    24,110
    Thanks
    53
    Thanked 2,618 Times in 2,568 Posts

    Default Re: Memory Leak in Java executor

    Also posted here: https://coderanch.com/t/741613/java/...-Java-executor
    If you don't understand my answer, don't ignore it, ask a question.

Similar Threads

  1. Memory Leak
    By Ami Bracha in forum What's Wrong With My Code?
    Replies: 5
    Last Post: December 26th, 2018, 09:12 AM
  2. Java application Memory Leak
    By Prem2310 in forum What's Wrong With My Code?
    Replies: 2
    Last Post: July 9th, 2013, 08:42 AM
  3. com.mysql.jdbc.JDBC4Connection suspected memory leak in java
    By newbie14 in forum JDBC & Databases
    Replies: 0
    Last Post: July 4th, 2013, 10:57 PM
  4. SImpeJDBCinsert leads to memory leak
    By justyStepi in forum JDBC & Databases
    Replies: 3
    Last Post: May 22nd, 2013, 11:26 AM
  5. [SOLVED] Memory usage increasing in while loop - is it a memory leak
    By mds1256 in forum What's Wrong With My Code?
    Replies: 2
    Last Post: July 18th, 2012, 10:06 AM