2012-10-20 4 views
8

Ich suche jetzt für 2 Wochen zu diesem Problem und scheint, dass ich keine Antwort nur im Web suchen finden kann.Perl Speicherverlust in Threads (Threads nicht Speicher freigeben)

So, hier ist zwei Stück Code:

1:

#! /usr/bin/perl 

# 
# RELEASE MEMORY 
# 

use threads; 

my @child; 

$ii=0; 


while (1) 
{ 
    my @child = threads->new(\&test, "test"); 
    $_->detach for @child; 
    print "$ii\n"; 
    $ii++; 
} 

sub test { 
    my ($ee) = 0;  
} 

2:

#! /usr/bin/perl 

# 
# DO NOT RELEASE MEMORY 
# 

use threads; 

my @child; 

$ii=0; 


for($ii=0;$ii<2000;$ii++) { 
    my @child = threads->new(\&test, "test"); 
    $_->detach for @child; 
    print "$ii\n"; 
} 

while(1) 
{ 
    sleep(10); 
} 

sub test { 
    my ($ee) = 0;  
} 

Also hier ist das Problem. Der erste Code läuft nur eine Endlosschleife und gibt den Speicher etwa alle 2 Sekunden zurück (nach ps)

Der zweite Code gibt auch Speicher frei, aber nur wenn er innerhalb der "for" -Schleife läuft. Sobald die for-Schleife verlassen und die Endlosschleife eingegeben wurde, wird der gesamte Speicher, der nicht in die for-Schleife freigegeben wurde, nie wieder an das Betriebssystem zurückgegeben.

Hat jemand das gleiche Problem?

Perl: (v5.16.1) gebaut für x86_64-Linux-thread-Multi

OS: Debian 6.0.5

Vielen Dank


Edit 1: I verwendet 800 Threads und alle verifiziert, dass sie durch Drucken der $ ee var.

Aber sobald Sie die while (1) Schleife eingeben, ist hier der ps aux | grep perl Ausgabe:

[email protected]:~# ps aux | grep perl 
root  6807 41.5 2.5 387780 209580 pts/0 S+ 16:38 0:02 /opt/ActivePerl-5.16/bin/perl /home/tttlast.pl 
root  7627 0.0 0.0 7548 856 pts/1 S+ 16:38 0:00 grep perl 

Also alles Thread beendet, aber die Speicherauslastung ist immer noch 2,5% meines Servers Gesamtspeicher. Also, wenn ich das Programm nicht abbringe, wird der Speicher immer noch benutzt.


Edit 2:

ich mein Problem gelöst, änderte ich meine Struktur. In der Tat wurde das Hauptprogramm (das lange laufende) getrennt und ich benutze ein kleines Programm, das wartet, bis alle Threads fertig sind.

Auf diese Weise füllt es nicht den virtuellen Speicher und andere Daemon werden nicht getötet.

Danke an alle, die mich zu dieser Lösung geführt haben.

+3

Ich habe sie auf OS X 10.8/Perl 5.16.0 ausprobiert. Das Verhalten, das ich zuerst sehe, ist die Speicherauslastung, die nach ein paar tausend Threads bei ungefähr 6 MEG resident ist. Die zweite Stufe ist etwa auf dem gleichen Niveau und bleibt dort im Schlaf. Der Thread-Speicher wird offensichtlich in beiden Fällen freigegeben. Könnten Sie weitere Beweise dafür posten, dass Speicher nicht freigegeben wird? Vielleicht die "ps" Ausgabe jede Sekunde? – Schwern

+0

Hinzugefügt die ps-Ausgabe. In der Tat ist das echte Programm komplexer, nur nicht hier, um nicht geflammt zu werden, aber es läuft für lange Zeit und jede Stunde öffnen etwa 250 bis 900 Threads, die den Speicher auf etwa 10% meines gesamten Speichers füllen und niemals freigeben . Aber genau so ist es im zweiten Beispiel. Lassen Sie es mich wissen, wenn Sie weitere Informationen benötigen. danke – user1761742

+1

Korrigiere mich, wenn ich falsch liege, aber nicht Perl * nur * Speicher frei wenn ein * Prozess * beendet? Dies war ein langjähriges "Feature", und ich konnte in den letzten Perldeltas keine Hinweise auf Optimierungen bezüglich Threading finden. Ich bin mehr überrascht von der * Abnahme * der Speicherauslastung, die Sie als Zeuge erlebt haben, als das "Leck". – amon

Antwort

4

Es gibt kein "Problem" hier. Dies ist alles normale, erwartete Verhalten. Wenn Sie dadurch ein Problem bekommen, haben Sie nicht erklärt, was es ist.

Es gibt keinen Grund, virtuellen Speicher zum Betriebssystem zurückzugeben, da virtueller Speicher keine knappe Ressource ist. Es gibt keinen Grund, physischen Speicher an das Betriebssystem zurückzugeben, da das Betriebssystem es übernehmen wird, wenn es trotzdem einen besseren Nutzen dafür hat.

Es gibt keinen Beweis dafür, dass es sich um ein Speicherleck handelt. Testergebnisse deuten darauf hin, dass es keinen Fall gibt, in dem die Speichernutzung ungebunden ansteigt - in allen Fällen gleicht sie sich schließlich ab.

+0

Nur verifiziert und Sie haben Recht. Der von anderen Prozessen verwendete Speicher wird verwendet, wenn das Perl-Programm Speicher benötigt. Das Problem ist, dass andere Prozesse aus dem Perl-Speicher wie Mysql und Mail-Server gelöscht werden. Und dass das Perl-Programm mysql und den Mailserver benutzt. Soll ich meinen Beitrag bearbeiten oder eine andere Frage stellen? Btw vielen Dank – user1761742

+1

Sie sollten nicht so viele Threads erstellen. Es ist nicht vernünftig. –

Verwandte Themen