递归堆内存,但没有(更长)循环?

时间:2014-03-15 23:16:37

标签: java recursion out-of-memory

我有一个分层的网格结构,每个节点都有一些父母和孩子。对于要添加到节点的对象,它必须满足该节点的规则。节点是这样的:子节点中包含的对象是父节点中对象的子集。当我在整个格子中运行时添加一个对象来添加对象。

    foreach Object g
          foreach Node in Lattice

             add g to Node

          End for
    End for

虽然这很简单,但格子非常大并且有很多对象可以通过,所以这似乎是浪费时间(尽管这种方法没有堆空间)因为有很多节点特定对象可能无效。

我宁愿在这方面改进程序的性能,因此实现了一个递归函数,它只将对象添加到晶格的顶部,然后继续尝试将它添加到子节点中,如果它是成功的:

   foreach Object g
         topNode.addObjectToMeAndAllChildren(g)
   End for

递归方法

   addObjectToMeAndAllChildren(Object obj){
          boolean success = addObject(obj)
          if(success)
               foreach kid in Children
                    kid.addObjectToMeAndAllChildren(obj);
               End for
   }

在大约16000个对象之后使用递归技术时,我遇到堆错误,但是不能想到为什么?它显然是在前15000左右工作,任何帮助将不胜感激。我希望我已经提供了足够的信息,而且我做了一些荒谬的事情。

Movie movie;    

try {
movie = data.getAFilm(index);

    //This piece of code works
    //for(RatingConcept r : concepts)
          //r.addOneObject(movie);

    //but this piece of code doesn't!
    concepts.get(0).addObjectToMeAndAllChildren(movie);


index++;
} catch (IndexOutOfBoundsException e) {
    e.printStackTrace();
     }

    //The next three methods are within the concept class
public void addObjectToMeAndAllChildren(Movie movie) {
            boolean success = addOneObject(movie);

    if(success){
        for(Concept kid : this.children){
             kid.addObjectToMeAndAllChildren(movie);
        }
    }

}

public boolean addOneObject(Movie addMe) {
    if (valid(addMe,minIndex,maxIndex,minValue,maxValue)) {
        objects.add(addMe); 
        hasSomething = true;
        return true;
    }
    return false;
}

protected static boolean valid(Movie test, int minIndex, int maxIndex,
                                    int minValue, int maxValue) {
    int[] distribution = test.getDistribution();

// to be valid only look at the range given by indexMax and Min Index
// and then see if they lie within the value ranges

     for(int i = minIndex; i <= maxIndex; i ++){
     if(distribution[i] > maxValue || distribution[i] < minValue){
            return false;
        }
    }
    return true;
}

我们很清楚,这是错误

 Exception in thread "Thread-3" Rating thread finished
 java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Unknown Source)
at java.util.ArrayList.grow(Unknown Source)
at java.util.ArrayList.ensureCapacityInternal(Unknown Source)
at java.util.ArrayList.add(Unknown Source)
at e.RatingConcept.addOneObject(RatingConcept.java:83)
at e.RatingConcept.addObjectToMeAndAllChildren(RatingConcept.java:142)
at e.RatingConcept.addObjectToMeAndAllChildren(RatingConcept.java:144)
at e.RatingConcept.addObjectToMeAndAllChildren(RatingConcept.java:144)
at e.RatingConcept.addObjectToMeAndAllChildren(RatingConcept.java:144)
at e.RatingConcept.addObjectToMeAndAllChildren(RatingConcept.java:144)
at e.RatingConcept.addObjectToMeAndAllChildren(RatingConcept.java:144)
at e.RatingConcept.addObjectToMeAndAllChildren(RatingConcept.java:144)
at e.RatingConcept.addObjectToMeAndAllChildren(RatingConcept.java:144)
at e.RatingConcept.addObjectToMeAndAllChildren(RatingConcept.java:144)
at e.RatingConcept.addObjectToMeAndAllChildren(RatingConcept.java:144)
at e.RatingConcept.addObjectToMeAndAllChildren(RatingConcept.java:144)
at e.RatingConcept.addObjectToMeAndAllChildren(RatingConcept.java:144)
at e.RatingBuilder.run(RatingBuilder.java:103)
at java.lang.Thread.run(Unknown Source)

1 个答案:

答案 0 :(得分:0)

你确定这是一个堆错误吗?如果你的递归方法不能进行尾递归,那么我认为递归函数调用可能已经耗尽了所有可用的堆栈。