2014-03-12 59 views
0

我在我的应用程序中有一个内存问题。我使用Jobschedular作为我的线程类。运行我的Java应用程序内存时不断增加。以下是我的代码。我曾尝试用system.gc &运行时垃圾回收也没有用处。请让我知道下面的线程类有什么问题。线程内存管理 - 作业调度

public class JobScheduler 
    implements Runnable 
{ 
    private class JobNode 
    { 

     public Runnable job; 
     public Date executeAt; 
     public long interval; 
     public int count; 

     private JobNode() 
     { 
     } 

    } 


    public JobScheduler() 
    { 
     dlock = new DaemonLock(); 
     jobs = new Vector(); 
     Thread js = new Thread(this); 
     js.setDaemon(true); 
     js.start(); 
    } 

    private synchronized void addJob(JobNode job) 
    { 
     dlock.acquire(); 
     jobs.addElement(job); 
     notify(); 
    } 

    public synchronized void relancerJOBsEnAttente() 
    { 
     notify(); 
    } 

    private synchronized void deleteJob(Runnable job) 
    { 
     int i = 0; 
     do 
     { 
      if(i >= jobs.size()) 
       break; 
      if(((JobNode)jobs.elementAt(i)).job.equals(job)) 
      { 
       jobs.removeElementAt(i); 
       dlock.release(); 
       break; 
      } 
      i++; 
     } while(true); 
    } 

    private JobNode updateJobNode(JobNode jn) 
    { 
     Calendar cal = Calendar.getInstance(); 
     cal.setTime(jn.executeAt); 
     if(jn.interval == -4L) 
     { 
      SchedulerAction sa = (SchedulerAction)jn.job; 
      MaDate md = MaDate.getPlusPetiteDate(sa.getElementScheduler().getListDaysOfWeek()); 
      if(md == null) 
       jn.count = 1; 
      else 
       jn.executeAt = new Date(getNextDateMD(md)); 
     } else 
     if(jn.interval == -3L) 
     { 
      //System.out.println("::: calculate WD :::"); 
      SchedulerAction sa = (SchedulerAction)jn.job; 
      jn.executeAt = new Date(getNextDateWD(jn.executeAt, sa.getElementScheduler().getListDaysOfWeek(), sa.getElementScheduler().getListWeeksOfMonth())); 
     } else 
     if(jn.interval == -1L) 
     { 
      cal.add(2, 1); 
      jn.executeAt = cal.getTime(); 
     } else 
     if(jn.interval == -2L) 
     { 
      cal.add(1, 1); 
      jn.executeAt = cal.getTime(); 
     } else 
     { 
      for(jn.executeAt = new Date(jn.executeAt.getTime() + jn.interval); 
           jn.executeAt.getTime() < (new Date(System.currentTimeMillis())).getTime(); 
           jn.executeAt = new Date(jn.executeAt.getTime() + jn.interval)); 
     } 
     jn.count = jn.count != -1 ? jn.count - 1 : -1; 
     return jn.count == 0 ? null : jn; 
    } 

    private synchronized long runJobs() 
    { 
     long minDiff = 0x7fffffffffffffffL; 
     long now = System.currentTimeMillis(); 
     JobNode jn = null; 
     for(int i = 0; i < jobs.size();) 
     { 
      jn = (JobNode)jobs.elementAt(i); 
      if(jn.executeAt.getTime() <= now) 
      { 
       Thread jt = new Thread(jn.job); 
       jt.setDaemon(false); 
       SchedulerAction act = (SchedulerAction)jn.job; 
       if(act.getElementScheduler().isWorking()) 
       { 
        act.getElementScheduler().getLogger().warn("########## NEXT SCHEDULE EXECUTION IMPOSSIBLE, TASK IS WORKING #######"); 
        act.getElementScheduler().getLogger().warn("########## (AT TIME : " + new Date(jn.executeAt.getTime()) + ") #######"); 
        act.getElementScheduler().getLogger().warn("########## EXTRACTION TAKE TO MUCH TIME OR PHAMTOM NOT RUNNING #######"); 
       } else 
       { 
        act.reactiverCondition(); 
        act.getElementScheduler().setProgressBarStart(); 
        ParametersStaticsLogsAndStatistics.addLog("SCHEDULER", "Information", Loader_Parameters_JBLoader.RESOURCES.getString("SCHED_START") + " << " + act.getElementScheduler().getTaskName() + " >> " + Loader_Parameters_JBLoader.RESOURCES.getString("SCHED_START_AT") + new Date(System.currentTimeMillis()), ""); 
        ParametersStaticsScheduler.listJobsWorking.add(act); 
        if(act.getElementScheduler().getFrequencyType().equals(Loader_Parameters_JBLoader.RESOURCES.getString("SCHED_FREQ_TYPE_IMM"))) 
        { 
         act.getElementScheduler().setStartTime(new Timestamp(System.currentTimeMillis())); 
         JPScheduler.tableScheduler.updateUI(); 
        } 
        act.getElementScheduler().initNbTables(); 
        act.getElementScheduler().setWorking(true); 
        System.out.println("*****************************************"); 
        System.out.println("START du task " + act.getElementScheduler().getTaskName()); 
        System.out.println("*****************************************"); 
        act.getElementScheduler().getLogger().info("# Commit count : " + GENERAL.getCommitCount()); 
        if(act.getElementScheduler().getProperties().isUseextractor()) 
         JPTreeTable.setEnableTreeTable(act.getElementScheduler().getPackageSelected().getTreeTable(), false); 
        if(act.getElementScheduler().getFrequencyType().equals(Loader_Parameters_JBLoader.RESOURCES.getString("SCHED_FREQ_TYPE_MD"))) 
        { 
         MaDate temp = MaDate.getPlusPetiteDate(act.getElementScheduler().getListDaysOfWeek()); 
         if(temp != null) 
          act.getElementScheduler().getListDaysOfWeek().remove(temp); 
        } 
        System.gc(); 
        jt.start(); 
       } 

       if(updateJobNode(jn) == null) 
       { 
        jobs.removeElementAt(i); 
        dlock.release(); 
       } else 
       { 
        Calendar c = Calendar.getInstance(); 
        c.setTimeInMillis(jn.executeAt.getTime()); 
        // 
        act.getElementScheduler().setCompletedTime(new Timestamp(jn.executeAt.getTime())); 
        //System.out.println("next datetime execute : " + act.getElementScheduler().getCompletedTime()); 
       } 
      } else 
      { 
       long diff = jn.executeAt.getTime() - now; 
       minDiff = Math.min(diff, minDiff); 
       i++; 
      } 
     } 

     return minDiff; 
    } 

    public synchronized void run() 
    { 
     do 
     { 
      long waitTime = runJobs(); 
      try 
      { 
       wait(waitTime); 
      } 
      catch(Exception e) { } 
     } while(true); 
    } 

    public void execute(Runnable job) 
    { 
     executeIn(job, 0L); 
    } 

    public void executeIn(Runnable job, long millis) 
    { 
     executeInAndRepeat(job, millis, 1000L, 1); 
    } 

    public void executeInAndRepeat(Runnable job, long millis, long repeat) 
    { 
     executeInAndRepeat(job, millis, repeat, -1); 
    } 

    public void executeInAndRepeat(Runnable job, long millis, long repeat, int count) 
    { 
     Date when = new Date(System.currentTimeMillis() + millis); 
     executeAtAndRepeat(job, when, repeat, count); 
    } 

    public void executeAt(Runnable job, Date when) 
    { 
     executeAtAndRepeat(job, when, 1000L, 1); 
    } 

    public void executeAtAndRepeat(Runnable job, Date when, long repeat) 
    { 
     executeAtAndRepeat(job, when, repeat, -1); 
    } 

    public void executeAtAndRepeat(Runnable job, Date when, long repeat, int count) 
    { 
     JobNode jn = new JobNode(); 
     jn.job = job; 
     jn.executeAt = when; 
     jn.interval = repeat; 
     jn.count = count; 
     addJob(jn); 
    } 

    public void executeAtAndRepeatWD(Runnable job, long time, List daysOfWeek, List weekOfMonth) 
    { 
     GregorianCalendar gc = new GregorianCalendar(); 
     gc.setTimeInMillis(time); 

     //test 
     //if (

     Date date = null; 
//  GregorianCalendar _tmp = gc; 
     int dow = gc.get(7); 
//  System.out.println("le premier dow est : " + dow); 
//  GregorianCalendar _tmp1 = gc; 
     int wom = gc.get(4); 
//  System.out.println("le premier wom est : " + wom); 
     // 
     boolean existe = false; 
     int i = 0; 
     do 
     { 
      // 
      if(i >= weekOfMonth.size()) 
       break; 
//   System.out.println("week du mois : " + (String)weekOfMonth.get(i)); 
//   System.out.println("index du wom : " + ParametersStaticsScheduler.getIndexWOM((String)weekOfMonth.get(i))); 
//   System.out.println("alors compararer wom et parameter avant"); 
      if(wom == ParametersStaticsScheduler.getIndexWOM((String)weekOfMonth.get(i))) 
      { 
       existe = true; 
       break; 
      } 
      if (ParametersStaticsScheduler.getIndexWOM((String)weekOfMonth.get(i)) == 1 && wom == 0){ 
       existe = true; 
       break; 
      } 

      i++; 
     } while(true); 
//  System.out.println("le wom final : " + wom); 

     if(!existe) 
     { 
      date = new Date(getNextDateWD(gc.getTime(), daysOfWeek, weekOfMonth)); 
//   System.out.println("date est : " + date); 
     } else 
     { 
      existe = false; 
      i = 0; 
      do 
      { 
//    System.out.println("second do..."); 
       if(i >= daysOfWeek.size()) 
        break; 
       if(dow == ParametersStaticsScheduler.getIndexDOW((String)daysOfWeek.get(i))) 
       { 
        existe = true; 
        break; 
       } 
       i++; 
      } while(true); 
      // 
//   System.out.println("le dow est : " + dow); 
      if(!existe) 
       date = new Date(getNextDateWD(gc.getTime(), daysOfWeek, weekOfMonth)); 
      else 
       date = gc.getTime(); 
      // 
//   System.out.println("date2 est : " + date); 
     } 
     GregorianCalendar tempo = new GregorianCalendar(); 
     tempo.setTime(date); 
//  GregorianCalendar _tmp2 = tempo; 
//  GregorianCalendar _tmp3 = gc; 
     tempo.set(10, gc.get(10)); 
//  GregorianCalendar _tmp4 = tempo; 
//  GregorianCalendar _tmp5 = gc; 
     tempo.set(12, gc.get(12)); 
     ((SchedulerAction)job).getElementScheduler().setStartTime(new Timestamp(tempo.getTimeInMillis())); 
//  System.out.println("l'executer a : " + tempo.getTime()); 
     executeAtAndRepeat(job, tempo.getTime(), -3L, -1); 
    } 

    public void executeAtAndRepeatMD(Runnable job, long time, List dateSelected) 
    { 
     GregorianCalendar gc = new GregorianCalendar(); 
     gc.setTimeInMillis(time); 
     MaDate temp = MaDate.getPlusPetiteDate(dateSelected); 
     long t = getNextDateMD(temp); 
     Date date = new Date(t); 
     GregorianCalendar gc_ = new GregorianCalendar(); 
     gc_.setTimeInMillis(date.getTime()); 
     gc_.set(10, gc.get(10)); 
     gc_.set(12, gc.get(12)); 
     executeAtAndRepeat(job, new Date(gc_.getTimeInMillis()), -4L, -1); 
    } 

    public long getNextDateWD(Date executeAt, List daysOfWeek, List weekOfMonth) 
    { 
     GregorianCalendar dAmain = new GregorianCalendar(); 
     dAmain.setTimeInMillis(executeAt.getTime()); 
     GregorianCalendar dAc = new GregorianCalendar(); 
     dAc.setTimeInMillis(dAmain.getTimeInMillis()); 
     // 
     //System.out.println("dAmain : " + dAmain.getTime()); 
     //System.out.println("dAc : " + dAc.getTime()); 
     GregorianCalendar dMin = null; 
     GregorianCalendar dT = null; 

     //x mise a jour du bug index = 0 en EUROPE et index = 1 en USA 
     int ws = 0; 
     boolean again = false; 

     //boucler 2 fois, si pas trouver au premier passage, sinon passer au mois suivant 
     for (int ind = 0; ind <= 1; ind++){ 
      //Parcourir de fisrt à last sélectionnés 
      for (int i = 0; i < weekOfMonth.size(); /*i++*/){ 

       //correction bug! 
       if (dAc.get(dAc.WEEK_OF_MONTH) == 0 && 
        ParametersStaticsScheduler.getIndexWOM ((String)weekOfMonth.get(i)) == 1 && 
        !again){ 
        //rien faire 
        again = true; 
        ws = 0; 
       } 
       else{ 
        again = false; 
        ws = ParametersStaticsScheduler.getIndexWOM ((String)weekOfMonth.get(i)); 
       } 


       //Parcourir les jours de la semaine 
       for (int j = 0; j < daysOfWeek.size(); j++){ 
        //obtenir la date pour un jour de la semaine donné et 
        //un weekend du mois donné 
//     System.out.println("getDateWD (" + dAc.getTime() + ", " + daysOfWeek.get(j) + ", " + weekOfMonth.get(i)); 
        dT = getDateWD(dAc, (String)daysOfWeek.get(j), ws); 
      //if (dT != null)System.out.println ("dT OBTENUE : " + dT.getTime()); 
        //else System.out.println("dT found is null!!!"); 
        // 
        if (dT != null){ 
         // la date Tempo est > date actuelle 
       //System.out.println (" - compara dT.compare(dAmain) > 0 : " + dT.compareTo(dAmain)); 
         if (dT.compareTo(dAmain) > 0){ 
          //garder la plus petite date 
          if (dMin == null){ 
           //System.out.println("dMin est null alors devien dT '"+dT+"'"); 
          // 
          dMin = dT; 
          } 
          else if (dMin.compareTo(dT) > 0){ 
           // 
           //System.out.println("dMin > dT ===> dMin = " + dT.getTime()); 
           dMin = dT; 

          } 
         } 
        } 
       }//for parcours jours de la semaine 
       if (again) {} 
       else{ i++; } 
      }//For parcours weeks de la semaine 

      //la date minimale trouve est différente que la date Actuelle 
      if (dMin != null){ 
       if (dMin.compareTo (dAmain) > 0 ) { 
        //mettre ajour jeure et minute e seconde pour le min (si jamis) 
        dMin.set(Calendar.HOUR, dAmain.get(Calendar.HOUR)); 
        dMin.set(Calendar.MINUTE, dAmain.get(Calendar.MINUTE)); 
        dMin.set(Calendar.SECOND, dAmain.get(Calendar.SECOND)); 
        break; 
       } 
      } 
      //si non continuer au mois suivant 
      dAc.set(dAc.DAY_OF_MONTH, 1); 
      dAc.add(dAc.MONTH, 1); 

     } 


     //System.out.println("Dmin found in 'getNextDateWD' --> " + dMin.getTime()); 
     return dMin.getTimeInMillis(); 
    } 

    /******************************* 
    * getDateWD 
    *******************************/ 
    public GregorianCalendar getDateWD(GregorianCalendar dA, String dow, int wom){ 
     // 
     GregorianCalendar gc = new GregorianCalendar(); 
     //gc.setTimeZone(TimeZone.getTimeZone("GMT+01:00")); 
//  gc.set(gc.ZONE_OFFSET); 

     try{ 
      gc.setTimeInMillis(dA.getTimeInMillis()); 
      //gc.setTimeZone(TimeZone.getTimeZone("GMT+01:00")); 
      // 
      int index = wom; 
//   System.out.println("index = " + index); 

//   if (index == ParametersStaticsScheduler.getIndexWOM(ParametersStaticsScheduler.LAST)){ 
//    System.out.println("last..... : " + gc.getActualMaximum(gc.WEEK_OF_MONTH)); 
//    index = gc.getActualMaximum(gc.WEEK_OF_MONTH); 
//   } 
//   else if (gc.get(gc.WEEK_OF_MONTH) == 0){ 
//   } 

//   System.out.println("ajouter au WEEK_OF MONT(" + (index - gc.get(gc.WEEK_OF_MONTH))); 
      gc.add (gc.WEEK_OF_MONTH, index - gc.get(gc.WEEK_OF_MONTH)); 
//   System.out.println("foutre le DAY_OF_WEEk a : " + ParametersStaticsScheduler.getIndexDOW (dow)); 
      gc.set (gc.DAY_OF_WEEK, ParametersStaticsScheduler.getIndexDOW (dow)); 

     }catch(Exception e){ 
      return null; 
     } 
     return gc; 
    } 


    public long getNextDateMD(MaDate dateSelected) 
    { 
     GregorianCalendar dA = new GregorianCalendar(); 
     dA.setTimeInMillis(System.currentTimeMillis()); 
     if(dateSelected == null) 
     { 
      return 0L; 
     } else 
     { 
      dA.set(1, dateSelected.getYear()); 
      dA.set(2, dateSelected.getMonth()); 
      dA.set(5, dateSelected.getDay()); 
      return dA.getTimeInMillis(); 
     } 
    } 

    public synchronized void deleteFromWaitingList(TElement_Scheduler tes) 
    { 
     try 
     { 
      for(int i = jobs.size() - 1; i >= 0; i--) 
      { 
       SchedulerAction act = (SchedulerAction)((JobNode)jobs.get(i)).job; 
       if(tes.getTaskId() == act.getElementScheduler().getTaskId()) 
       { 
        jobs.removeElementAt(i); 
        dlock.release(); 
       } 
      } 

     } 
     catch(Exception e) 
     { 
      System.err.println("Exception e : " + e.getMessage()); 
     } 
    } 

    public synchronized void supendsAll() 
    { 
     try 
     { 
      for(int i = jobs.size() - 1; i >= 0; i--) 
      { 
       jobs.removeElementAt(i); 
       dlock.release(); 
      } 

     } 
     catch(Exception e) { } 
    } 

    public void executeAtNextDOW(Runnable job, Date when, int DOW) 
    { 
     Calendar target = Calendar.getInstance(); 
     target.setTime(when); 
     for(; target.get(7) != DOW; target.add(5, 1)); 
     executeAt(job, target.getTime()); 
    } 

    public void configureBackup(Runnable job) 
    { 
     Calendar now = Calendar.getInstance(); 
     executeAtNextDOW(job, now.getTime(), 1); 
    } 

    public static final int ONCE = 1; 
    public static final int FOREVER = -1; 
    public static final long HOURLY = 0x36ee80L; 
    public static final long DAILY = 0x5265c00L; 
    public static final long WEEKLY = 0x240c8400L; 
    public static final long MONTHLY = -1L; 
    public static final long YEARLY = -2L; 
    public static final int WEEKLY_OPTION = -3; 
    public static final int MONTHLY_OPTION = -4; 
    private DaemonLock dlock; 
    private Vector jobs; 
} 
+0

我的猜测是作业矢量不断增长。有一个'deleteJob'方法,但不使用该方法。 – vanOekel

+0

嗨VanOekel,你是对的。作业矢量不断增加内存。但我在我的代码中删除了JobJob方法。 – Karthick88it

回答

0

我们不能通过查看这样的代码来找出造成内存泄漏的原因。所以,你真正需要做的是以下内容:

第一:而内存泄漏使用vesualVM跟踪您的应用程序,产生堆转储和线程转储,然后分析堆,你会发现,采取的具体对象大量的内存和线程转储会告诉你你当前正在执行的代码在哪里,之后你就可以修复你的代码。

二:你需要看看JVM内存参数,它会帮助您优化应用程序

1)该参数将无法避免内存泄漏,但其良好的知道:

-Xmx2048m -> this param to set the max memory that the JVM can allocate 
-Xms1024m -> the init memory that JVM will allocate on the start up 
-XX:MaxPermSize=512M -> this for the max Permanent Generation memory 

2)此参数将加快GC所以GC将有更多比例来清理你的内存

-XX:MaxNewSize= -> this need to be 40% from your Xmx value 
-XX:NewSize=614m -> this need to be 40% from your Xmx value 

3)从来没有使用System.gc,使用CMS垃圾收集器。

-XX:+UseConcMarkSweepGC 
+0

请注意,使用CMS会增加内存占用量。如果延迟不是问题,请使用parallell gc(大多数机器上的默认设置)或G1收集器。我同意不调用System.gc()。如果你有内存泄漏问题,调用gc将无济于事。 – Erik

+0

嗨艾瑞克,谢谢你的回复。我没有任何内存泄漏在我的应用程序。当我运行runJobs()方法时,我正在增加内存。 – Karthick88it

+0

亲爱的Salah,我跟踪了我的应用程序,问题仅在runJob()方法中。对此方法有任何想法。 – Karthick88it