2010-11-18 6 views
1

J'ai tout un programme ..Erlang HEAP débordement

est presque complet ..

Cependant, je vois un accident de tas après environ 12 heures de fonctionnement.

Je me souviens d'avoir entendu dire que vous ne pouviez pas programmer erlang d'une certaine manière, sinon quand vous recuriez la pile. Quelqu'un peut-il fournir un exemple de cela?

Et y a-t-il aussi un moyen d'avoir un moniteur en temps réel sur les processus qui s'empilent?

Cordialement

EDIT - Qu'en est-

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

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

Votre modification est récursive, ce qui signifie qu'elle ne génère rien sur la pile. – Lukas

+2

Comme @TERRIBLE ADVICE souligne très correctement votre modification n'est pas la queue récursive – rvirding

Répondre

8

Même votre édition est pas récursive:

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

L'ordre d'exécution pour une fonction est: receive ... end, loop(). Maintenant, si vous obtenez un message {sys, _}, loop/0 sera appelé à partir de la réception, la transformation de l'ordre d'exécution ci-dessus dans quelque chose d'équivalent à:

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

Le problème est que si vous appelez loop() à partir de la réception, la VM doit encore stocker le point de retour afin d'exécuter le loop() en place après le receive.

Pour rendre votre récursive fonction, vous devez faire soit:

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

ou

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

Où appeler loop() est vraiment toujours la dernière chose à faire dans le fonction.

+0

Grande réponse, je vous donnerais plus de votes si je pouvais! – BAR

1

Quelque chose comme cela pourrait être utilisé pour surveiller l'utilisation du tas actuel de processus dans votre système. Il suffit de le mettre dans une impression dans un gen_server en boucle ou simplement le lancer dans le shell de temps en temps.

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