perl Hauptspeicher
am 30.05.2006 15:52:07 von georg.heiss
Hallo,
kann mir jemand erklären warum perl die 6 mal soviel Hauptspeicher
belegt wie ich erwartet hätte? Mein Erwartungswert =3D10.000 kB,
Realität =3D61.560 kB mit folgendem Aufruf:
bash-2.03$ perl mem.pl 1000000
loop :=3D 1000000 * 10 Byte
pid, name, user, cpu, ram, swap (kByte)
6172 perl heissge 0.0 2152 3192
6172 perl heissge 1.0 53360 54376
6172 perl heissge 1.9 61560 62568
6172 perl heissge 2.2 61560 62568
------------------------------------------------------------ ---------------=
------------
#!/opt/perl/bin/perl
# $Id: mem.pl 1006 2006-05-29 12:00:08Z heissge $
#
my @big1 =3D ();
my @big2 =3D ();
my $pid =3D $$;
print "loop :=3D $ARGV[0] * 10 Byte\n";
print "pid, name, user, cpu, ram, swap (kByte)\n";
system("/usr/bin/ps -A -o pid=3DID -o fname=3DName -o user=3DOwner -o
pcpu,rss=3DRAM -o vsz |grep $pid");
push (@big1,'1234567890') for(1..$ARGV[0]);
system("/usr/bin/ps -A -o pid=3DID -o fname=3DName -o user=3DOwner -o
pcpu,rss=3DRAM -o vsz |grep $pid");
@big1 =3D ();
push (@big2,'1234567890') for(1..$ARGV[0]);
system("/usr/bin/ps -A -o pid=3DID -o fname=3DName -o user=3DOwner -o
pcpu,rss=3DRAM -o vsz |grep $pid");
@big2 =3D ();
system("/usr/bin/ps -A -o pid=3DID -o fname=3DName -o user=3DOwner -o
pcpu,rss=3DRAM -o vsz |grep $pid");
Re: perl Hauptspeicher
am 30.05.2006 16:41:31 von Helmut Wollmersdorfer
georg.heiss@gmx.de wrote:
> Hallo,
> kann mir jemand erklären warum perl die 6 mal soviel Hauptspeicher
> belegt wie ich erwartet hätte? Mein Erwartungswert =10.000 kB,
> Realität =61.560 kB mit folgendem Aufruf:
> bash-2.03$ perl mem.pl 1000000
> loop := 1000000 * 10 Byte
[...]
> @big1 = ();
> push (@big2,'1234567890') for(1..$ARGV[0]);
1. sind das nicht 10 Byte sondern 10 *Character*. Für die interne
Repräsentation eines Characters werden vermutlich mehr als ein Byte
verwendet.
2. verbraucht die Verwaltung der Elemente einer Liste auch Speicherplatz.
Hauptanteil dürfte 2. haben - leicht modifiziert:
helmut@xp2400:$ perl ./test.pl 10000000
loop := 10000000 * 1 Byte
pid, name, user, cpu, ram, swap (kByte)
7753 perl helmut 0.0 1344 4788
7753 perl helmut 102 472296 475836
helmut@xp2400:$ perl ./test.pl 100000
loop := 100000 * 100 Byte
pid, name, user, cpu, ram, swap (kByte)
8605 perl helmut 0.0 1340 4788
8605 perl helmut 0.0 15160 18616
Helmut Wollmersdorfer
Re: perl Hauptspeicher
am 30.05.2006 16:52:45 von Frank Seitz
georg.heiss@gmx.de wrote:
> kann mir jemand erklären warum perl die 6 mal soviel Hauptspeicher
> belegt wie ich erwartet hätte?
Weil Deine Erwartung naiv ist, dass Perl für die Speicherung
eines String von 10 Zeichen Länge nicht mehr als 10 Bytes benötigt
und dass ein Array keinerlei Platzbedarf hat.
Tatsächlich benötigt ein String der Länge n in Perl 25+n Bytes.
Ein Array mit 1000000 Elementen benötigt 4000152 Bytes.
Das macht bei Deinem Array mit den 1000000 Elementen
zusammen 39000152 Bytes.
(alles Perl 5.8.6)
---------
#!/usr/local/bin/perl -w
use strict;
use Devel::Size qw(size total_size);
print 'String : ',size('1234567890'),"\n";
my @arr = ('1234567890') x 1000000;
print 'Array : ',size(\@arr),"\n";
print 'Zusammen: ',total_size(\@arr),"\n";
__END__
String : 35
Array : 4000052
Zusammen: 39000052
Grüße
Frank
--
Dipl.-Inform. Frank Seitz; http://www.fseitz.de/
Anwendungen für Ihr Internet und Intranet
Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel
Re: perl Hauptspeicher
am 30.05.2006 16:59:44 von Frank Seitz
Helmut Wollmersdorfer wrote:
> 1. sind das nicht 10 Byte sondern 10 *Character*. Für die interne
> Repräsentation eines Characters werden vermutlich mehr als ein Byte
> verwendet.
Richtig, das spielt auch noch mit rein. Bei Unicode-Zeichen
außerhalb des ASCII-Bereichs sind es nicht 25+n Bytes, wie ich
in meinem vorigen Posting schrieb, sondern entsprechend mehr.
> 2. verbraucht die Verwaltung der Elemente einer Liste auch Speicherplatz.
>
> Hauptanteil dürfte 2. haben - leicht modifiziert:
>
> helmut@xp2400:$ perl ./test.pl 10000000
> loop := 10000000 * 1 Byte
> pid, name, user, cpu, ram, swap (kByte)
> 7753 perl helmut 0.0 1344 4788
> 7753 perl helmut 102 472296 475836
> helmut@xp2400:$ perl ./test.pl 100000
> loop := 100000 * 100 Byte
> pid, name, user, cpu, ram, swap (kByte)
> 8605 perl helmut 0.0 1340 4788
> 8605 perl helmut 0.0 15160 18616
Devel::Size ist schöner :)
Grüße
Frank
--
Dipl.-Inform. Frank Seitz; http://www.fseitz.de/
Anwendungen für Ihr Internet und Intranet
Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel
Re: perl Hauptspeicher
am 30.05.2006 17:19:25 von Mirco Wahab
Thus spoke georg.heiss@gmx.de (on 2006-05-30 15:52):
> kann mir jemand erklären warum perl die 6 mal soviel Hauptspeicher
> belegt wie ich erwartet hätte? Mein Erwartungswert =10.000 kB,
> Realität =61.560 kB mit folgendem Aufruf:
Wie Frank schon sagte, es ist naiv anzunehmen,
dass perl die Arrays C-Like (als Feld von Daten)
speichert.
Tatsächlich ist es so, dass Perl ein Array
von /Zeigern/ auf nicht-alloziierte Strukturen
vorhält, jedes *belegte* Arrayelement bekommt dann
nochmal (s)eine speziell initialisierte Struktur.
C:
int array[] ==> | 4 bytes data | 4 bytes data | 4 bytes data | ...
Perl:
@array ==> | 4 bytes pointer | 4 bytes pointer | 4 bytes pointer | ...
| | |
| | |
V V V
{Struct Scalar} {Struct Scalar} {Struct Scalar}
(So ungefähr jedenfalls ... vereinfacht ausgedrückt)
Viele Grüße
Mirco
Re: perl Hauptspeicher
am 30.05.2006 17:35:00 von Frank Seitz
Mirco Wahab wrote:
> Thus spoke georg.heiss@gmx.de (on 2006-05-30 15:52):
>>
>>kann mir jemand erklären warum perl die 6 mal soviel Hauptspeicher
>>belegt wie ich erwartet hätte? Mein Erwartungswert =10.000 kB,
>>Realität =61.560 kB mit folgendem Aufruf:
>
> Wie Frank schon sagte, es ist naiv anzunehmen,
> dass perl die Arrays C-Like (als Feld von Daten)
> speichert.
>
> Tatsächlich ist es so, dass Perl ein Array
> von /Zeigern/ auf nicht-alloziierte Strukturen
> vorhält, jedes *belegte* Arrayelement bekommt dann
> nochmal (s)eine speziell initialisierte Struktur.
>
>
> C:
> int array[] ==> | 4 bytes data | 4 bytes data | 4 bytes data | ...
>
> Perl:
> @array ==> | 4 bytes pointer | 4 bytes pointer | 4 bytes pointer | ...
> | | |
> | | |
> V V V
> {Struct Scalar} {Struct Scalar} {Struct Scalar}
>
>
>
> (So ungefähr jedenfalls ... vereinfacht ausgedrückt)
Eine Ergänzung noch zu den Byte-Angaben (gilt auch für
mein Posting), die beziehen sich auf eine 32Bit-Architektur.
Grüße
Frank
--
Dipl.-Inform. Frank Seitz; http://www.fseitz.de/
Anwendungen für Ihr Internet und Intranet
Tel: 04103/180301; Fax: -02; Industriestr. 31, 22880 Wedel
Re: perl Hauptspeicher
am 30.05.2006 18:57:55 von Helmut Wollmersdorfer
Frank Seitz wrote:
> Richtig, das spielt auch noch mit rein. Bei Unicode-Zeichen
> außerhalb des ASCII-Bereichs sind es nicht 25+n Bytes, wie ich
> in meinem vorigen Posting schrieb, sondern entsprechend mehr.
Nun ja, ich dachte zuerst, dass Perl so wie andere Programmiersprachen
eine fixe Anzahl Bytes pro Character intern verwendet. Anscheinend wird
aber im sparsamen UTF-8 gespeichert.
> Devel::Size ist schöner :)
Danke - kannte ich nicht.
Helmut Wollmersdorfer
Re: perl Hauptspeicher
am 31.05.2006 08:28:42 von Ferry Bolhar
Helmut Wollmersdorfer:
> kann mir jemand erklären warum perl die 6 mal soviel Hauptspeicher
> belegt wie ich erwartet hätte? Mein Erwartungswert =10.000 kB,
> Realität =61.560 kB mit folgendem Aufruf:
[...]
Perl legt Stringwerte nicht einfach als char* ab, sondern es verwendet
dafür (wie auch für alle numerischen Werte) Datenstrukturen, die als
"SV" (= Scalar Value) bezeichnet werden. Eine solche Datenstruktur
benötigt - noch ohne den eigentlichen Wert! - bereits 24 Bytes, hinzu
kommt das in C üblicher Nullbyte zum Terminieren einer Zeichenkette.
Das heißt, bereits der Wert
""
(Leerstring) benötigt 25 Bytes Speicherplatz! Und ein String mit Länge
somit 25 + Bytes (auf 32-Bit-Architekturen; unter 64 Bit
sind es sogar 33 Bytes). Und wenn Unicode-Zeichen abgespeichert
werden (Perl verwendet dazu das UTF-8 Format), dann werden
für jedes Nicht-ASCII-Zeichen mindestens 2 Byte Speicherplatz
benötigt. Der Wert "undef" kommt immerhin mit "nur" 12 Bytes aus.
Zum Verwalten von Arrays verwendet Perl eine Struktur names "AV"
(Array Value), die in der einfachsten Form zumindest 40 Bytes benötigt
(60 Bytes auf 64 Bit), dazu kommen dann noch mindestens 29 Bytes
_pro_ Arrayelement (= pro Element ein Pointer à vier Bytes plus der
jeweilige SV). Deine Rechunng von 1:1 Stringlänge : Speicherbedarf
ist also nicht ganz richtig...
LG, Ferry
--
Ing. Ferry Bolhar
Municipality of Vienna, Department 14
A-1010 Vienna / AUSTRIA
E-mail: bol@adv.magwien.gv.at