我在我的應用程序中有一個內存問題。我使用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;
}
我的猜測是作業矢量不斷增長。有一個'deleteJob'方法,但不使用該方法。 – vanOekel
嗨VanOekel,你是對的。作業矢量不斷增加內存。但我在我的代碼中刪除了JobJob方法。 – Karthick88it