Schrift
Wiki:Tipp zum Debugging: use Data::Dumper; local $Data::Dumper::Useqq = 1; print Dumper \@var;
[thread]7827[/thread]

Perl und Garbage collector: Warum macht der Perl GC nichts?



<< |< 1 2 >| >> 15 Einträge, 2 Seiten
Gast Gast
 2006-03-24 18:37
#64052 #64052
hi!

Ich hab ein Problem, dass Perl Speicher nicht freigibt, der aber eigentlich nicht mehr referenziert wird (glaube ich) und versuche es in folgendem Bsp darzustellen. Es ist auf das wesentliche reduziert, um das Problem darzustellen. Ich hab Perl 5.8.4. auf Debian Sarge.

Eigentlich spielt sich das bei mir in einer subroutine ab. Ich habs aber auch noch in ein package gesteckt um sicherzugehen, dass nichts mehr referenziert wird.
Also:

----main-------------------------------------------------------------------
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
use p; # mein package

my $p=p->new ();
$p->x();          # die funktion, sonst nichts
$p=undef;

for (;;) # damit ich mir noch den speicher anschaun kann
{  sleep (1);print ".";  }

--------p.pm--------------------------------------
package p;
       my $class = shift;
       my $self = {};
       bless $self, $class;
       return $self;
}


sub x()
{
my $x;
my $str = "asfsdafssssssaaaaaadfsaf";
for (my $z=0;$z <1000000; $z++)
{ $x.= $str; }
#tut nichts ausser speicher fressen
}

-------------------------------------------------------------------------------

edit pq: code-tags hinzugefügt\n\n

<!--EDIT|pq|1143222579-->
renee
 2006-03-24 20:58
#64053 #64053
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Perl handhabt es etwas anders, als Du Dir vielleicht vorstellst. Der Speicher wird bei Perl nicht wieder an das Betriebssystem zurückgegeben, sondern wird im Laufe des Programms für etwas anderes verwendet (wenn benötigt)...
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
Relais
 2006-03-24 22:22
#64054 #64054
User since
2003-08-06
2246 Artikel
ModeratorIn
[Homepage] [default_avatar]
[quote=renee,24.03.2006, 19:58]Perl handhabt es etwas anders, als Du Dir vielleicht vorstellst. Der Speicher wird bei Perl nicht wieder an das Betriebssystem zurückgegeben, sondern wird im Laufe des Programms für etwas anderes verwendet (wenn benötigt)...[/quote]
Können Programme während ihrer Laufzeit Speicher an das OS zurückgeben? Wie geht das?
Erst denken, dann posten --
27. Deutscher Perl- u. Raku -Workshop (Termin wird noch gesucht) 2025 in München.

Winter is Coming
Ronnie
 2006-03-24 23:10
#64055 #64055
User since
2003-08-14
2022 Artikel
BenutzerIn
[default_avatar]
[quote=Relais,24.03.2006, 21:22]Können Programme während ihrer Laufzeit Speicher an das OS zurückgeben? Wie geht das?[/quote]
AFAIR, wird vom Heap (http://de.wikipedia.org/wiki/Heap_%28Speicher%29) angeforderter Speicher bei Bedarf wieder freigegeben. Ein C-Programmierer könnte da sicher besser Auskunft geben.
ptk
 2006-03-25 02:17
#64056 #64056
User since
2003-11-28
3645 Artikel
ModeratorIn
[default_avatar]
[quote=Relais,24.03.2006, 21:22][quote=renee,24.03.2006, 19:58]Perl handhabt es etwas anders, als Du Dir vielleicht vorstellst. Der Speicher wird bei Perl nicht wieder an das Betriebssystem zurückgegeben, sondern wird im Laufe des Programms für etwas anderes verwendet (wenn benötigt)...[/quote]
Können Programme während ihrer Laufzeit Speicher an das OS zurückgeben? Wie geht das?[/quote]
Mir fallen zwei Möglichkeiten ein:
1. Speicherblöcke können per mmap belegt werden und dann einfach wieder mit munmap entfernt werden. Da mmap etwas teuer ist, macht man das typischerweise nur bei großen Speicherblöcken.
2. Wenn Speicherblöcke am Ende des Data-Segments freigegeben werden, kann das Data-Segment wieder geschrumpft werden. Leider ist das Schrumpfen Glückssache. Nehmen wir an, dass ein riesiger Speicherblock belegt und dann einen winzigen Speicherblock hinter dem riesigen anlegt wird. Jetzt wird der riesige Speicherblock freigegen. Das Data-Segment kann aber nicht verkleinert werden, weil sich am Ende der winzige Speicherblock befindet. Dieser kann auch nicht verschoben werden, weil mit Sicherheit (C-)Zeiger auf ihn zeigen.
esskar
 2006-03-25 04:59
#64057 #64057
User since
2003-08-04
7321 Artikel
ModeratorIn

user image
[quote=Relais,24.03.2006, 21:22]Können Programme während ihrer Laufzeit Speicher an das OS zurückgeben? Wie geht das?[/quote]
ich kann jetzt nur von windows sprechen:
ein prozess hat - egal wieviel RAM der computer hat - 2 GB virtuellen speicher (RAMD + SWAP). Diesen kann er beliebig nutzen.

Unter C/C++ kann man zwischen zwei Arteb von Speicher unterschienden. Code-Speicher und Stack-Speicher (@Ronnie: in uralt C Zeiten kannte man Heap noch gar nicht)

eine
Code: (dl )
char var[512];
belegt z.b. 512 bytes vom code speicher, wobei ein
Code: (dl )
char *var = new char[512]
512 bytes auf dem stack belegt. Code-speicher kann man nicht - zumindeest nicht durch anschupsen - an das OS wieder zurück geben. Speicher Stack schon, und zwar mit
Code: (dl )
delete var
.

Wenn man sich ein Progamm unter Windows im TaskManager anschaut, kann man beobachten wie Speicher konsumiert und freigegeben wird. Wenn die Perl.exe läuft, sieht man, dass kein Speicher freigegeben wird, es wird nur ggf keiner mahr konsumiert.

PS: Preisfragen an die C Leute
1: was ist der Unterschied zwischen char *x; und char x[]; (beides global) und
2: extern char *x; und extern char x[]; (auch wieder global)\n\n

<!--EDIT|esskar|1143255709-->
chris01
 2006-03-25 12:02
#64058 #64058
User since
2006-03-25
1 Artikel
BenutzerIn
[default_avatar]
so, ich bin der urfragesteller, jetzt aber registriert.

1. ich glaube nicht, dass die diskussion um C bzw. CS, SS und DS was bring, da perl ja interpretiert und daher meine ich auch alle seine daten auf den heap legt. und der heap kann sicher auch fragmentiert sein.

2. der unterschied zwischen * und [] liegt ganz einfach im typ. * ist ein pointer, der irgendwo hinzeigen kann. [] kennzeichnet ein feld, dass je nach angabe fix reserviert wird.

3. ich hab jetzt schon selbst etwas herumgespielt. es scheint zustimmen, dass perl speicher nicht wieder zurückgibt, ihn jedoch wiederverwendet. ob das schlau ist, kann man diskutieren.
esskar
 2006-03-25 13:04
#64059 #64059
User since
2003-08-04
7321 Artikel
ModeratorIn

user image
zu deinem 2: char *x kostet 4 bytes (auf einem 32bit system) auf dem stack. char x[] kostet 4 bytes im programspeicher.

extern *x kostet 4 bytes auf dem stack. extern x[] kostet nichts.

zu deinem 3: ich denke, es ist nicht schlau, da das betriebssystem an der stelle wohl immer schlauer ist. es ist einfach egoistisch und einfach so implementiert, und in Perl 5.x auch wohl nicht mehr zu ändern
ptk
 2006-03-25 13:33
#64060 #64060
User since
2003-11-28
3645 Artikel
ModeratorIn
[default_avatar]
Man hat die Wahl. Beim Kompilieren von Perl kann man sich entscheiden, ob man das malloc von Perl oder das betriebssystem-eigene malloc verwendet, letzteres mit -Uusemymalloc. Meistens ist das wieder eine Abwägungssache zwischen Geschwindigkeit und Speicherverbrauch. Zum Beispiel kann das FreeBSD-malloc Speicher an das Betriebssystem zurückgeben, aber das scheint zu Lasten der Geschwindigkeit zu gehen. Im FreeBSD-Hintfile steht:
Code: (dl )
1
2
3
# In FreeBSD 4 and 5 the system malloc is performance-wise
# VERY bad for Perl-- we are talking of differences of not
# one, but TWO magnitudes.

Und deshalb wird bei FreeBSD das malloc von Perl verwendet.
Bei Linux hingegen wird das System-malloc verwendet:
Code: (dl )
1
2
3
# The system malloc() is about as fast and as frugal as perl's.
# Since the system malloc() has been the default since at least
# 5.001, we might as well leave it that way.
murphy
 2006-03-25 14:05
#64061 #64061
User since
2004-07-19
1776 Artikel
HausmeisterIn
[Homepage]
user image
[quote=esskar,25.03.2006, 11:04]zu deinem 2: char *x kostet 4 bytes (auf einem 32bit system) auf dem stack. char x[] kostet 4 bytes im programspeicher.

extern *x kostet 4 bytes auf dem stack. extern x[] kostet nichts.
[...][/quote]
Also bei mir erzeugen sowohl "extern char *bla;" als auch "extern char bla[];" identischen Objektcode. "char bla[];" erzeugt als Definition einer globalen Variablen erwartungsgemäß einen Fehler, "char *bla;" funktioniert und erzeugt einen Pointer in einem Datensegment.

Ehrlich gesagt wüsste ich auch nicht, wieso ein vernünftiger C-Compiler das anders handhaben sollte. Insbesondere habe ich es noch nie gesehen, dass ein C-Compiler für eine globale Variable Speicher auf dem Stack reserviert. Das wäre ja auch ziemlich dumm, weil man dann nicht andere Objekte gegen diese Variable linken könnte.
When C++ is your hammer, every problem looks like your thumb.
<< |< 1 2 >| >> 15 Einträge, 2 Seiten



View all threads created 2006-03-24 18:37.