NT: Speicherbedarf von Perl-Skripten

Hallo,

ich habe eine Frage zum Speicherbedarf bei der Ausfuehrung von Perl Skripten. Ich habe ein Skript das mitsamt allen Modulen ca. 1 MB an Source-Code hat (die Module werden auch alle per "use" eingebunden). Von der Geschwindigkeit o.ae. gab es bisher keine Probleme, aber bei meinem Schlund&Partner Account laeuft es nicht mehr, weil es anscheinend die 10 MB Speichergrenze ueberschreitet.

Kann es sein das allein der geladene Source Code soviel Speicher braucht (dann muesste ich irgendwie probieren die Dateien aufzuteilen), oder muessen da noch irgendwelche "Memory-Leaks" sein?
Vielleicht kennt sich irgendjemand in dieser Richtung aus...

Vielen Dank schonmal, Gruesse,
   -> Nils

  1. hallo
    nunja. wenn es irgendwelche speicherprobleme oder sonstiges hat, dann dürfte es auch nicht laufen, wenn es auf einem server den du auf deinem PC eingerichtet hast probierst.
    ansonsten: sollte es einfach nur ewig laden (scheinbar unendlich lange) lass es einfach mal mindestens 10 minuten laden... wenn du viel mit Dateien arbeitest, kann das seine zeit dauern.
    viel glück mit den tips.
    matthias huttar

  2. Hallo,

    Kann es sein das allein der geladene Source Code soviel Speicher braucht (dann muesste ich irgendwie probieren die Dateien aufzuteilen), oder muessen da noch irgendwelche "Memory-Leaks" sein?

    Aus der Ferne kann ich das nur schwer einschätzen.
    Ich hab mal folgendes propiert:
    (Das alles unter Win2K, Activestate Perl Build 623)

    c:> perl  [ca. 1.7 MByte Speicherbedarf]
    use CGI;   [ca. 4 MByte]
    use DBI;   [ca. 5.3 MByte]
    for $i( 0...10000)
      {
      push @d,"sdjflkjfsdlkjldskjlksdflksfdlkdj";
      }

    $x = <STDIN>; # nur daß das script nicht beendet wird
    [ca. 6 MByte]
     bzw.
    for $i( 0...10000)
      {
      $h{$i} = "ddklfjkldslkjsdlkfjlksdjlfkjsdlkj";
      }
    $x = <STDIN>;
    [ca. 8.8 MByte]

    wobei der Unterschied von 2.3 MByte bei 'use CGI;' schon einiges sagt. Allein anhand der Größe des Sources läßt sich sowas also nicht abschätzen.

    Folgende Vorschläge:
    1.) versuche die internen Datenstrukturen so minimal wie möglich zu halten.
    Beispiel:
    <code memory="much">
    open(BLABLA,'x.x');
    my @inhalt = <BLABLA>; # schlecht, da der gesmate Dateiinhalt in ein Array gepackt wird
    my $line;
    foreach $line(@inhalt)
      {
      &machwasmit($line);
      }
    </code>

    <code memory="lesser">
    open(BLABLA,'x.x');
    while(<BLABLA>)
      {
      &machwasmit($_);
      }
    </code>

    2.) Versuche, die Lebensdauer von Strukturen auf ein Minimum zu beschränken
    Einen Block um ein bestimmtes Stück Code hilft oft schon ungemein

    <code memory="not as much as before">
    {
    open(BLABLA,'x.x');
    my @inhalt = <BLABLA>; # schlecht, da der gesmate Dateiinhalt in ein Array gepackt wird
    my $line;
    foreach $line(@inhalt)
      {
      &machwasmit($line);
      }
    }

    ab hier gibts @inhalt nicht mehr

    </code>

    3.) Verwende alternativ zu 'use' 'require'.
    Der hier wesentliche Unterschied ist, daß 'require' erst dann ausgeführt wird, wenn das Script auch den Code ausführt, während 'use' bereits zur Comiletime ausgeführt wird, unabhängig davon, ob das Modul im script jemals gebraucht wird.
    Natürlich geht das nicht immer, aber wenn Du einige Deiner Module nicht immer brauchst, ist das eine Überlegung wert.

    empfehlenswerte Lektüre dazu:
    perldoc -f use
    perldoc -f require

    So, jetzt fältt mir nichts mehr ein, aber es gibt sicherlich noch einige andere Dinger, welche Dir helfen können, den Speicherbedarf des Scripts in Grenzen zu halten.
    Ich hab vor kurzen auch das Problem gehabt, da hat das Script zu viele interne Strukturen angelegt, und dann brauchte es plötzlich im worst case 100+ MByte :-(

    Ich hoffe, einigermaßen weitergeholfen zu haben.

    Grüße
      Klaus

    1. Hallo,

      vielen Dank schonmal fuer die Tips (auch an Matthias)! Das hoert sich sehr interessant an - eine Frage noch: wie hast du denn rausgekriegt wieviel Speicher das Skript braucht?

      Danke,Gruesse,
          -> Nils

      1. Hallo,

        • eine Frage noch: wie hast du denn rausgekriegt wieviel Speicher das Skript braucht?

        Tja, starte einfach perl mit
        c:> perl

        Jetzt kannst Du den gewünschten Code einfahc eingeben. jedes use wird sofort ausgeführt, der Rest des scripts nach EOF (unter Linux Ctrl-D, unter Windows Ctrl-Z).
        Wenn Du dann unter WinNT bzw Win2K den Taskmanager gestartet hast, kannst Du unter Prozesse den Speicherbedarf des aktiven Perl-Prozesses ermitteln.
        unter Linux kriegst Du das z.B. mit 'top -p Prozessid_von_perl' recht gut raus.

        Grüße
          Klaus