Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/359.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用以下递归方法时获取java.lang.OutOfMemoryError异常_Java_Recursion_Out Of Memory - Fatal编程技术网

使用以下递归方法时获取java.lang.OutOfMemoryError异常

使用以下递归方法时获取java.lang.OutOfMemoryError异常,java,recursion,out-of-memory,Java,Recursion,Out Of Memory,基本上,下面的方法是遍历节点并创建一个类似于图的结构。创建的对象超过400K,导致OutOfMemoryError。有人可以帮助优化下面的代码 方法: private static PolicyNodeInfo[] mapPolicySteps(PolicyTreatmentNodeInfo fromObj) { List<PolicyNodeInfo> tmpList = new ArrayList<PolicyNodeInfo>(); Po

基本上,下面的方法是遍历节点并创建一个类似于图的结构。创建的对象超过400K,导致OutOfMemoryError。有人可以帮助优化下面的代码

方法:

    private static PolicyNodeInfo[] mapPolicySteps(PolicyTreatmentNodeInfo fromObj)
 {

    List<PolicyNodeInfo> tmpList = new ArrayList<PolicyNodeInfo>();
    PolicyTreatmentNodeInfo[] childrens = fromObj.getChildrenPolicyInfo(); 
    // Get object policy node children

    if(childrens != null) //if there are no children return empty list
    {
        for(PolicyTreatmentNodeInfo child : childrens) 
        //for each children map the object and recursively go over his children
        {
            if(null!=child)
             {
                if(X3ServerUtil.isStringNotEmptyNotNull(child.getStepName())&& 
                   !child.getStepName().startsWith("Dummy")) 
             //case child is not null (edge) or it's not non operation step (need to ignore)
                    {   
                    int index = tmpList.size();
                    tmpList.add(insertStep(child)); //insert current node

                    tmpList.get(index).setPolicyTreatmentNodeInfoList(mapPolicySteps(child)); 
                    //insert recursively all child nodes
                }
                else
                {
                handleDummyChildNodeInsertion(tmpList, child);
                }
            }
        }
    }
        return tmpList.toArray(new PolicyNodeInfo[tmpList.size()]);
}
私有静态PolicyNodeInfo[]映射PolicySteps(PolicyTreatmentNodeInfo fromObj)
{
List tmpList=new ArrayList();
PolicyTreatmentNodeInfo[]childrens=fromObj.getChildrenPolicyInfo();
//获取对象策略节点子节点
if(childrens!=null)//如果没有子项,则返回空列表
{
for(PolicyTreatmentNodeInfo儿童:儿童)
//对于每个子对象,映射对象并递归地遍历其子对象
{
if(null!=子级)
{
if(X3ServerUtil.IsStringNotyNotNull(child.getStepName())&&
!child.getStepName().startsWith(“Dummy”))
//case child不为null(边缘)或它不是非操作步骤(需要忽略)
{   
int index=tmpList.size();
tmpList.add(insertStep(child));//插入当前节点
get(index).setPolicyTreatmentNodeInfo列表(mapPolicySteps(child));
//递归插入所有子节点
}
其他的
{
handleDummyChildNodeInsertion(tmpList,child);
}
}
}
}
返回tmpList.toArray(新策略节点信息[tmpList.size()]);
}
异常:(Stack.java:23) weblogic.kernel.ThreadLocalStack$StackInitialValue.initialValue(ThreadLocalStack.java:159) 在 FinalThreadLocal$FinalThreadStorage.(FinalThreadLocal.java:208) 位于weblogic.kernel.AuditableThread(AuditableThread.java:13) 截断的。有关完整的堆栈跟踪,请参阅日志文件


图形结构类似于下面的一个,有49个节点。由于可能有多条路径,方法的调用次数超过了400K次。

递归对于遍历大型数据集是危险的,因为堆栈内存实际上不在您的控制之下。(换句话说:我在学校学到了递归是一种“最优雅”的解决方案,在大学里我学到了“不要做”的方法——去吧

 I have faced same and resolved by using Garbage collector. There is multiple way to resolve this issue.
 1. Define scope of data members and make sure garbage collector is in picture.
 2. increase java memory for your Environment.
 https://www.wikihow.com/Increase-Java-Memory-in-Windows-7
要消除这种情况,请使用适当的数据结构展开,例如,沿着以下线路展开队列:

Deque<MyObject> queue = ...
queue.push(rootElement);
while (!queue.isEmpty()) {
    MyObject currentElement = queue.poll();
    // ... process current element
    // and in the end: push children
    currentElement.getChildren().forEach(child -> queue.push(child));
}
Deque队列=。。。
push(rootElement);
而(!queue.isEmpty()){
MyObject currentElement=queue.poll();
//…处理当前元素
//最后:推孩子
currentElement.getChildren().forEach(child->queue.push(child));
}
对于深度优先遍历,请使用堆栈(即
pop()
而不是
poll()


如果仍然出现内存不足错误,则必须增加堆空间或同时使用不同的方法。

问题出在这一行
tmpList.get(index.setPolicyTreatmentNodeInfo(mapPolicySteps(child))
这里的通话顺序是
mapPolicySteps(child)
首先被调用,只有当它返回
时才被调用。SetPolicyTreatmentNodeInfo列表(/*从mapPolicySteps(child)*/)返回的内容将被调用。
。 这会创建大量等待
mapPolicySteps
函数结束的堆栈帧

您需要找到一种方法,使
mapPolicySteps
函数在最后一次调用。
(称为)

谢谢你的帮助。我们一直在努力解决这个问题,并提出了以下解决方案,效果良好。在下面张贴答案。:)

//创建了类级hashmap
public static Map executedElementMap=new HashMap();
//正在遍历的节点都存储在映射中。
//在遍历任何节点之前,只需检查节点是否已被遍历,如果已被遍历,只需添加节点并跳过遍历。
私有静态PolicyNodeInfo[]映射PolicySteps(PolicyTreatmentNodeInfo fromObj)
{
List tmpList=new ArrayList();
PolicyTreatmentNodeInfo[]childrens=fromObj.getChildrenPolicyInfo();//获取对象策略节点子节点
if(childrens!=null)//如果没有子项,则返回空列表
{
for(policytreamentnodeinfo-child:childrens)//对于每个子对象,映射对象并递归地遍历其子对象
{
if(null!=子级)
{
布尔值isNodeTraversed=executedElementMap.containsKey(child.getStepName());
如果(!isNodeTraversed)
{
executedElementMap.put(child.getStepName(),child);
if(X3ServerUtil.IsStringNotyNotNull(child.getStepName())和&!child.getStepName().startsWith(非操作步骤的前缀)//case child不为null(边缘)或它不是非操作步骤(需要忽略)
{   
int index=tmpList.size();
tmpList.add(insertStep(child));//插入当前节点
tmpList.get(index.setPolicyTreatmentNodeInfo列表(mapPolicySteps(child));//递归插入所有子节点
}
其他的
{
handleDummyChildNodeInsertion(tmpList,child);
}
}  
否则{
tmpList.add(insertStep(child));
}
}
}
}
返回tmpList.toArray(新策略节点信息[tmpList.size()]);
}

在问题/post中添加了异常。请将其作为问题的一部分,而不是作为注释发布。您要创建多少元素?请记住,对于重新声明和实例化tmpList的每个方法调用。。。变量,这将导致系统资源耗尽基本上,该图仅包含49个元素,但一个节点可以是多个节点的后续节点。多少次
  //Created a class level hashmap
public static Map<String,PolicyNodeInfo> executedElementMap=new HashMap<String,PolicyNodeInfo>();  

// Whichever node is being traversed is stored in the map.
// Before Traversing any node , just checking whether the node has already been traversed , if traversed just add the node and skip the traversing.

private static PolicyNodeInfo[] mapPolicySteps(PolicyTreatmentNodeInfo fromObj)

{
    List<PolicyNodeInfo> tmpList = new ArrayList<PolicyNodeInfo>();
    PolicyTreatmentNodeInfo[] childrens = fromObj.getChildrenPolicyInfo(); // Get object policy node children
    if(childrens != null) //if there are no children return empty list
    {
        for(PolicyTreatmentNodeInfo child : childrens) //for each children map the object and recursively go over his children
        {
            if(null!=child)
                {
                Boolean isNodeTraversed= executedElementMap.containsKey(child.getStepName());
                  if(!isNodeTraversed)
                  {
                    executedElementMap.put(child.getStepName(), child);
                    if(X3ServerUtil.isStringNotEmptyNotNull(child.getStepName())&& !child.getStepName().startsWith(PREFIX_FOR_NON_OPERATION_STEP)) //case child is not null (edge) or it's not non operation step (need to ignore)
                    {   
                        int index = tmpList.size();
                        tmpList.add(insertStep(child)); //insert current node
                        tmpList.get(index).setPolicyTreatmentNodeInfoList(mapPolicySteps(child)); //insert recursively all child nodes
                    }
                    else
                    {
                        handleDummyChildNodeInsertion(tmpList, child);
                    }
                 }  
                 else{
                      tmpList.add(insertStep(child));  
                     }
              }
        }
    }
    return tmpList.toArray(new PolicyNodeInfo[tmpList.size()]);
}