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;

}

>

[10897 byte] By [Theloniusa] at [2007-11-27 3:49:01]
# 1

First of all, explicit garbage collection is worthless. The JVM is guaranteed to run the gc before throwing OutOfMemoryError.

Secondly, how much heap are you giving the Java program? You might want to try to double it first to see if that helps.

Also make sure you're not keeping references around to any huge arrays/collections or similar things that might cause a memory leak.

Also forget nulling the local variables at the end of the method, that's useless as well (the variables go out of scope when the method ends).

And last, try to divide the code into maybe a few additional methods. That spaghetti code looks quite horrible and will cause problems.

-Kayaman-a at 2007-7-12 8:52:51 > top of Java-index,Java Essentials,Java Programming...