Код падает на итерации 86 - PullRequest
       2

Код падает на итерации 86

2 голосов
/ 24 февраля 2011
static void Job47(Args _args)
 {
 str                                  path,stx;
 TreeNodeIterator                     iter;
 TreeNode                             treeNode, treeNodeToRelease;
 Map                                  dictMenuDisplay;
 FormName                             formName;
 MenuItemName                         menuItemName;
 container                            conMenu;
 int                                  i,n;
   ;

 for (n=1;n<=100;n++)
       {
        info(strfmt("iter:%1",n));
        path            ="Menu Items\\Display";
        dictMenuDisplay = new Map(Types::String,Types::Container);
        treenode        = Treenode::findNode(path);
        iter            = treenode.AOTiterator();
        treenode        = iter.next();

        while (treenode)
          {
          formName     = treenode.AOTgetProperty("Object");
          menuItemName = treenode.AOTname();

           if (dictMenuDisplay.exists(formName))
            {
             conMenu = dictMenuDisplay.lookup(formName);
             conMenu = conIns(conMenu,conlen(conMenu)+1,menuItemName);
             dictMenuDisplay.insert(formName,conMenu);
             }

           else
             dictMenuDisplay.insert(formName,[menuItemName]);
                      //  treenode = iter.next();

           if(treeNodeToRelease && SysTreeNode::isApplObject(treeNode))
            {
             treeNodeToRelease.treeNodeRelease();
             treeNodeToRelease=null;
            }

           if(SysTreeNode::isApplObject(treeNode))
            {
              treeNodeToRelease=treeNode;
            }

            treeNode=iter.next();
        }
    }
  }

Я получаю ошибку "переполнение во внутреннем стеке выполнения", код работает до 86-й итерации правильно, помогите ...

Ответы [ 3 ]

3 голосов
/ 25 февраля 2011

Ядро не сразу собирает мусор в объектах TreeNode. Как только вы закончили с триодом для объекта приложения и всех его дочерних элементов, вам нужно вызвать TreeNode.treeNodeRelease(), а затем treeNode=null;, чтобы очистить сборщик мусора.

...
TreeNode treeNodeToRelease;
...

while(treenode)
{

    ... /* do stuff with treenode */

    if(treeNodeToRelease && SysTreeNode::isApplObject(treeNode))
    {
        treeNodeToRelease.treeNodeRelease();
        treeNodeToRelease=null;
    }
    if(SysTreeNode::isApplObject(treeNode))
    {
        treeNodeToRelease=treeNode;
    }
    treeNode=iter.next();
}
0 голосов
/ 17 мая 2011

Цитата из руководства:

Если вы запустите этот метод ( treeNodeRelease () ) на многих узлах дерева в одном и том же исполнении, он может потребовать ресурсов. По мере продвижения вы должны выгружать узлы дерева, чтобы сборщик мусора мог их удалить.

Обязательно удалите все ссылки на узел дерева и его подузлы, прежде чем вызывать этот метод.

Также у вас есть как минимум 85 ссылок на treeNodeToRelease (и treeNode!), Плавающие вокруг -> call treeNodeToRelease.treeNodeRelease () в конце вашего внешнего цикла.

0 голосов
/ 19 марта 2011

Код:

 if(treeNodeToRelease && SysTreeNode::isApplObject(treeNode))

следует заменить на:

 if (treeNodeToRelease)

Освобождение объекта не должно зависеть от следующего объекта.

или, возможно,этого достаточно (вытесняя решение Джея):

while (treenode)
{
    ... /* do stuff with treenode */
    treeNode.treeNodeRelease();
    treeNode = iter.next();
}
...