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.
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
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
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