我的应用程序中存在内存问题。我使用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 :(得分: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