2010-11-18 9 views
1

Ich habe ein ziemlich Programm ..Erlang Heapüberlauf

Sein fast vollständig ..

Jedoch habe ich nach ca. 12 Stunden Lauf einen Haufen Absturz sehe.

Ich erinnere mich zu hören, dass Sie Erlang nicht auf eine bestimmte Weise programmieren können, wenn nicht, wenn Sie den Stack rekursieren. Kann mir jemand ein Beispiel dafür geben ??

Und gibt es auch eine Möglichkeit, einen Echtzeitmonitor zu haben, welcher Prozess sich "stapelt"?

Grüße

EDIT - Was ist

loop() -> 
    receive 
    {sys, Msg} -> 
     handle_sys_msg(Msg), 
     loop(); 
    {From, Msg} -> 
      Reply = handle_msg(Msg), 
      From ! Reply, 
      loop(); 

    _ -> continue 
    end, 
    loop(). 
+0

Ihre Bearbeitung ist tail rekursiv, was bedeutet, dass nichts auf dem Stack erstellt wird. – Lukas

+2

Als @TERRIBLE ADVICE sehr richtig darauf hinweist, dass Ihre Bearbeitung ist nicht Schwanz rekursiv – rvirding

Antwort

8

Auch deine Bearbeitung ist nicht tail-rekursive:

loop() -> 
    receive 
    {sys, Msg} -> 
     handle_sys_msg(Msg), 
     loop(); 
    {From, Msg} -> 
      Reply = handle_msg(Msg), 
      From ! Reply, 
      loop(); 
     _ -> continue 
    end, 
    loop(). 

Die Reihenfolge der Ausführung für eine Funktion ist: receive ... end, loop().

loop() -> 
     receive 
      loop() -> 
       receive 
        ... 
       end, 
       loop(), 
     end, 
     loop() -> 
     ... 

Das Problem ist, dass, wenn Sie loop() aus dem Empfang nennen, die: Nun, wenn Sie eine {sys, _} Nachricht erhalten, loop/0 wird aus dem erhalten, der Umwandlung die Reihenfolge der Ausführung oben in etwas Gleichwertiges zu nennen Die VM muss immer noch den Rückkehrpunkt speichern, um die loop() an Ort und Stelle nach der receive zu betreiben.

Um Ihre Funktion tail-rekursive zu machen, würden Sie tun müssen, um entweder:

loop() -> 
    receive 
    {sys, Msg} -> 
     handle_sys_msg(Msg); 
    {From, Msg} -> 
      Reply = handle_msg(Msg), 
      From ! Reply; 
     _ -> continue 
    end, 
    loop(). 

oder

loop() -> 
    receive 
    {sys, Msg} -> 
     handle_sys_msg(Msg), 
     loop(); 
    {From, Msg} -> 
      Reply = handle_msg(Msg), 
      From ! Reply, 
      loop(); 
     _ -> loop() 
    end. 

Wo loop() wirklich immer das letzte, was in der getan werden muss Aufruf Funktion.

+0

Große Antwort, würde ich Ihnen mehr Stimmen geben, wenn ich könnte! – BAR

1

So etwas wie dies für die Überwachung der aktuellen Heap-Nutzung von Prozessen in Ihrem System verwendet werden könnten. Einfach in einen Loop-Gen-Server einlesen oder einfach mal in der Shell laufen lassen.

lists:reverse(lists:keysort(2, 
    [{Pid,catch element(2,process_info(Pid,total_heap_size))} || Pid <- processes()])).