Hans-Peter Rieger: Rekursive Funktion legt PC lahm

Hallo JavaScript-Experten,

wenn man glaubt, man hat so ziemlich alles mal erlebt, was man so erleben kann, dann passiert folgendes: Es wird eine rekursive JavaScript-Funktion verwendet zum Erstellen einer Explorer-ähnlichen Navigation.

Der Effekt: Wenn das Ganze (a) auf dem heimischen IIS läuft, hängt sich die Funktion in der ersten Rekursions-Schleife auf, die CPU-Auslastung steigt auf 100 % und die Speichernutzung (lt. Task-Manager) läuft gegen die obere Grenze. Es wird also permanent Speicher allokiert. Baut man dagegen (b) als erste Zeile zu Test-Zwecken ein alert("pieps!") ein, funktioniert die Funktion tadellos. Lade ich die Funktion (incl. ihrer HTML-Datei) auf einen IIS ins Internet, läuft die Funktion in jedem Fall tadellos (also auch ohne alert). Woran - um alles in der Welt - kann das liegen ?

Die Funktion (zur Information):

function funDrawBranch (iBegEntry, iLevel, sPrev, iSelected)
{  var j;
   iSave[iLevel] = i  ;                          // save actual loop counter value
   for (i = iBegEntry; i <= mD.length; i++)      // partial loop over menu entries
   {  if (mD[i].type == "root")
      {  filMenuFile.write ("<img src="" + mD[i].oicon + "" align=top>");
         filMenuFile.write (mD[i].etext + "<br>\n");
      }
      if (mD[i].prev == sPrev)
      {  for (j = 1; j <= (iLevel - 1); j++)
         {  if (iHigherIcon[j] == 101)  {  filMenuFile.write ("<img src="Branch_101c.gif" align=top>");  }
            if (iHigherIcon[j] == 000)  {  filMenuFile.write ("<img src="Empty.gif"       align=top>");  }
         }
         if (mD[i].type == "folder")
         {  if (mD[i].open == true)
            {  if (mD[i].tail == true)  {  filMenuFile.write ("<a href="javascript:parent.LounFrame.funFolder(false, " + i + ")"><img src="Branch_110m.gif" align=top border=0></a>");  }
               else                     {  filMenuFile.write ("<a href="javascript:parent.LounFrame.funFolder(false, " + i + ")"><img src="Branch_111m.gif" align=top border=0></a>");  }
                                           filMenuFile.write ("<a href="javascript:parent.LounFrame.funFolder(false, " + i + ")"><img src="" + mD[i].oicon + "" align=top border=0></a>");
                                           filMenuFile.write ("<a href="javascript:parent.LounFrame.funFolder(false, " + i + ")">" + mD[i].etext + "</a><br>\n");
               if (mD[i].tail == true)  {  iHigherIcon[iLevel] = 000;  }
               else                     {  iHigherIcon[iLevel] = 101;  }
               funDrawBranch (i+1, iLevel+1, mD[i].name, iSelected);
            }
            else
            {  if (mD[i].tail == true)  {  filMenuFile.write ("<a href="javascript:parent.LounFrame.funFolder(true, " + i + ")"><img src="Branch_110p.gif" align=top border=0></a>");  }
               else                     {  filMenuFile.write ("<a href="javascript:parent.LounFrame.funFolder(true, " + i + ")"><img src="Branch_111p.gif" align=top border=0></a>");  }
                                           filMenuFile.write ("<a href="javascript:parent.LounFrame.funFolder(true, " + i + ")"><img src="" + mD[i].cicon + "" align=top border=0></a>");
                                           filMenuFile.write ("<a href="javascript:parent.LounFrame.funFolder(true, " + i + ")">" + mD[i].etext + "</a><br>\n");
            }
         }
         if (mD[i].type == "leaf")
         {  if (mD[i].tail == true)     {  filMenuFile.write ("<img src="Branch_110c.gif" align=top>");  }
            else                        {  filMenuFile.write ("<img src="Branch_111c.gif" align=top>");  }
                                           filMenuFile.write ("<img src="" + mD[i].oicon + "" align=top>");
            if (i == iSelected)         {  filMenuFile.write ("<a href="" + mD[i].url + "" target="" + mD[i].tframe + "">" + mD[i].etext + "</a><br>\n");    }
            else                        {  filMenuFile.write ("<a href="" + mD[i].url + "" target="" + mD[i].tframe + "">" + mD[i].etext + "</a><br>\n");    }
         }
      }
   }
   i = iSave[iLevel];
}                                                // end of ... function

Ciao
Hans-Peter

  1. Hallo JavaScript-Experten,

    wenn man glaubt, man hat so ziemlich alles mal erlebt, was man so erleben kann, dann passiert folgendes: Es wird eine rekursive JavaScript-Funktion verwendet zum Erstellen einer Explorer-ähnlichen Navigation.

    Der Effekt: Wenn das Ganze (a) auf dem heimischen IIS läuft, hängt sich die Funktion in der ersten Rekursions-Schleife auf, die CPU-Auslastung steigt auf 100 % und die Speichernutzung (lt. Task-Manager) läuft gegen die obere Grenze. Es wird also permanent Speicher allokiert. Baut man dagegen (b) als erste Zeile zu Test-Zwecken ein alert("pieps!") ein, funktioniert die Funktion tadellos. Lade ich die Funktion (incl. ihrer HTML-Datei) auf einen IIS ins Internet, läuft die Funktion in jedem Fall tadellos (also auch ohne alert). Woran - um alles in der Welt - kann das liegen ?

    Das die Abruchbedigung lokal nicht erreicht wird?

    Es ist aus dem wust an Quellcode schwer ersichtlich, wann die rekursion gestoppt wird und wie es erreicht werden soll.

    Struppi.

    1. Hi Struppi,

      ja ich habe mir überlegt, ob ich den Quellcode überhaupt mit poste ... ist ja nicht ganz trivial. Die Funktion hat jahrelang getan was sie tun soll; ich ahne deshalb irgendwie, dass die Funktion selber gar nicht der Grund für das Problem ist. Die Abbruchbedingung wird mit einem alert() als ersten Befehl erreicht, dann sollte sie doch auch ohne alert() ebenfalls erreicht werden. Immerhin ändert ein alert() nichts am Ablauf, sondern unterbricht den Ablauf nur temporär.

      (seufz)
      Hans-Peter

      1. Hi Struppi,

        ja ich habe mir überlegt, ob ich den Quellcode überhaupt mit poste ... ist ja nicht ganz trivial. Die Funktion hat jahrelang getan was sie tun soll; ich ahne deshalb irgendwie, dass die Funktion selber gar nicht der Grund für das Problem ist. Die Abbruchbedingung wird mit einem alert() als ersten Befehl erreicht, dann sollte sie doch auch ohne alert() ebenfalls erreicht werden. Immerhin ändert ein alert() nichts am Ablauf, sondern unterbricht den Ablauf nur temporär.

        sicher, aber guck dir doch noch mal dein Quelltext an, der ist hier einfach niocht durchschaubar, insofern kann man dir auch keinen Rat geben.

        Struppi.