java.lang.OutOfMemoryError: Java heap space
Hey everyone!
I have a little problem. Currently I am working on a software to help teachers in school find good substitutions in case a teacher is missing. My problem is that during the calculation i sometimes get java.lang.OutOfMemoryError: Java heap space if the input is large. I already have explicit GC at i dunno how many spots and still i have it. What is most weird, is that i also have the error AFTER the method is finished and explicit GC should have freed up plenty of memory. After the calculation i am back on the GUI and not doing anything big at all.
So my question is: when do objects get dereferenced and collectable for the GC? I also set all variables of bigger then int-size to null explicitly in the end of the function - no difference.
I also get the error with smaller inputs, if i do the calculation several times after another, so it cannot be cause of an endless loop or such in the method.
My Code for the function is the following. All objects are small and consist of little data, as in some strings or ints.
Any ideas how to solve the problem?
I dunno what to do anymore...
public SubstitutionPlan optimizeFast(SubstitutionPlan plan)throws ConnectionNotEstablishedException, SQLException, IOException, DatabaseLockedException{
// If no substitutions are put in, optimisation is finished already
if (plan.getSubstitutions() ==null || plan.getSubstitutions().length == 0)return plan;
Settings set = Settings.getInstance();
SubstitutionsController sc =new SubstitutionsController();
TeachersController tc =new TeachersController();
float[][] matrix;
int[] ar;
int period;
Date date;
Sclass[] sclasses;
Sclass sclass;
Subject[] ns;
Subject subject ;
RatedTeacher[] freeTeacher ;
float[] curRates;
int[] optResult;
// Go through all periods
for (int hour = 0; hour < set.getMaxNumberOfPeriods(); hour++){
Stack st =new Stack();
Stack t =new Stack();
//If border periods should not be substituted and period is a border period then continue
ar = set.getMorningBorderPeriods();
if (ar.length>0){
Arrays.sort(ar);
if (Arrays.binarySearch(ar, hour)>=0)continue;
}
ar = set.getAfternoonBorderPeriods();
if (ar.length>0){
Arrays.sort(ar);
if (Arrays.binarySearch(ar, hour)>=0)continue;
}
for (int teacher = 0; teacher<plan.getSubstitutions().length; teacher++){
// Explicite garbage collection, so memory is free
Runtime.getRuntime().gc();
// Skips all null substitutions or fixed ones
if (plan.getSubstitutions()[teacher][hour]==null
|| plan.getSubstitutions()[teacher][hour].isFixed())continue;
// If the "substitute upper grade flag is set to false in the settings
// skip the sclass if it is an upper grade.
if (!set.substituteUpperGrades() && plan.getSubstitutions()[teacher][hour]!=null && plan.getSubstitutions()[teacher][hour].getStudyUnit().getSclass()!=null){
sclasses = set.getUpperGrades();
if (SclassController.search(sclasses, plan.getSubstitutions()[teacher][hour].getStudyUnit().getSclass()))continue;
}
// Skip all non subjects
ns = set.getNonSubjects();
if (plan.getSubstitutions()[teacher][hour].getStudyUnit().getSubject() !=null
&& SubjectsController.search(ns, plan.getSubstitutions()[teacher][hour].getStudyUnit().getSubject()))continue;
//Skip all non classes
sclasses = set.getNonClasses();
if (plan.getSubstitutions()[teacher][hour].getStudyUnit().getSclass() !=null
&& SclassController.search(sclasses, plan.getSubstitutions()[teacher][hour].getStudyUnit().getSclass()))continue;
// Get the possible substitutes
sclass = plan.getSubstitutions()[teacher][hour].getStudyUnit().getSclass();
period = plan.getSubstitutions()[teacher][hour].getStudyUnit().getPeriod();
date = plan.getDate();
subject = plan.getSubstitutions()[teacher][hour].getStudyUnit().getSubject();
freeTeacher = tc.getPossibleSubstitutesUnsorted(sclass, subject, date, period);
curRates =newfloat[freeTeacher.length];
for (int j = 0; j >< freeTeacher.length; j++){
curRates[j] = freeTeacher[j].getRating();
}
st.push(curRates);
t.push(freeTeacher);
freeTeacher =null;
}
// If there is nothing to substitute continue
if (st.empty())continue;
// prepare the optimisation matrix
matrix =newfloat[st.size()][((float[])st.peek()).length];
// the teachers that will be looked at in the optimisation
Stack teachers =new Stack();
for (int i = st.size()-1; i >= 0 ; i--){
matrix[i] = (float[])st.pop();
teachers.push(t.pop());
}
try{
// optimize the matrix
optResult = this.greedy(matrix);
matrix =null;
int count = 0;
// set the teachers in the substitutions
for (int teacher = 0; teacher<plan.getSubstitutions().length; teacher++){
// Skips all null substitutions or fixed ones
if (plan.getSubstitutions()[teacher][hour]==null || plan.getSubstitutions()[teacher][hour].isFixed())continue;
// If the "substitute upper grade flag is set to false in the settings
// skip the sclass if it is an upper grade.
if (!set.substituteUpperGrades() && plan.getSubstitutions()[teacher][hour]!=null && plan.getSubstitutions()[teacher][hour].getStudyUnit().getSclass()!=null){
sclasses = set.getUpperGrades();
if (SclassController.search(sclasses, plan.getSubstitutions()[teacher][hour].getStudyUnit().getSclass()))continue;
}
// Skip all non subjects
ns = set.getNonSubjects();
if (plan.getSubstitutions()[teacher][hour].getStudyUnit().getSubject() !=null
&& SubjectsController.search(ns, plan.getSubstitutions()[teacher][hour].getStudyUnit().getSubject()))continue;
//Skip all non classes
sclasses = set.getNonClasses();
if (plan.getSubstitutions()[teacher][hour].getStudyUnit().getSclass() !=null
&& SclassController.search(sclasses, plan.getSubstitutions()[teacher][hour].getStudyUnit().getSclass()))continue;
plan.getSubstitutions()[teacher][hour].setSubstitute(((RatedTeacher[])teachers.pop())[optResult[count++]].getTeacher());
sc.save(plan.getSubstitutions()[teacher][hour]);
}
}catch (IncompatibleInputException iie){
plan.addProblemPeriod(hour);
}
}
matrix=null;
ar=null;
date=null;
sclasses=null;
sclass=null;
ns=null;
subject=null;
freeTeacher=null;
curRates=null;
optResult=null;
return plan;
}
>

