Uploaded image for project: 'WildFly'
  1. WildFly
  2. WFLY-3823

Memory leak with EJB Timer service

    Details

    • Type: Bug
    • Status: Closed (View Workflow)
    • Priority: Major
    • Resolution: Done
    • Affects Version/s: 8.1.0.Final
    • Fix Version/s: 9.0.0.Alpha1
    • Component/s: EJB
    • Labels:
      None
    • Environment:

      Windows 8.1 64bit, Java 1.7.0_40-b43

    • Steps to Reproduce:
      Hide

      Create a simple web app with only one class.

      TestScheduler.java
      package com.inqool;
      
      import javax.ejb.Schedule;
      import javax.ejb.Singleton;
      
      @Singleton
      public class TestScheduler {
          @Schedule( hour = "6", dayOfMonth = "*", persistent=false)
          public void automaticTimeout() {
      
          }
      }
      

      Deploy and undeploy the application. Using any profiling tools one will find out, that the classloader is not released.

      Show
      Create a simple web app with only one class. TestScheduler.java package com.inqool; import javax.ejb.Schedule; import javax.ejb.Singleton; @Singleton public class TestScheduler { @Schedule( hour = "6" , dayOfMonth = "*" , persistent= false ) public void automaticTimeout() { } } Deploy and undeploy the application. Using any profiling tools one will find out, that the classloader is not released.

      Description

      There is a memory leak during undeploy (redeploy) when there is a timer used in EJB bean.

      When the timer is created (using @Schedule or programmatically), it is put in queue on Timer thread. According to JDK sources (http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/7u40-b43/java/util/Timer.java#Timer line 552) The queue is processed if new timer is created or the next timer task is due to be run and the reference to last timer is retained on stack (line 521). Therefore after the module undeploy there is still a reference to TimerTask from the module.

      It is not a true memory leak, because the reference will be removed when the task is due, but in environment with many redeploys (development and continuous integration) will soon hit the java.lang.OutOfMemoryError: PermGen space.

      One workaround is to have another Scheduler, which will schedule job for every second. This way, the timer thread will process the queue and throw away the reference to last timerTask.

        Gliffy Diagrams

          Attachments

            Activity

              People

              • Assignee:
                swd847 Stuart Douglas
                Reporter:
                backslash47 Matus Zamborsky
              • Votes:
                0 Vote for this issue
                Watchers:
                2 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: