Schrift
[thread]10776[/thread]

Objekt löschen (Seite 3)

Tags: Ähnliche Threads

Leser: 2


<< |< 1 2 3 >| >> 26 Einträge, 3 Seiten
renee
 2007-11-14 13:03
#102398 #102398
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Struppi+2007-11-14 11:36:37--
Ich hab noch nie mit mod_perl gearbeitet, aber das klingt als ob du von mod_perl abrätst?


Ich würde nicht *generell* davon abraten, aber bei mod_perl sollte man ganz genau wissen was man tut. Einem Einsteiger würde ich nicht unbedingt zu mod_perl raten. Da kann man ganz schnell in fiese Fallen tappen!

Quote
[...]
Das klingt einerseits nach einem globalen Objekt. Ist es unter mod_perl nicht sinnvoll dieses im Speicher zu halten, bzw. ist das nicht der Vorteil von mod_perl, das eben nicht immer alles neu geladen wird?

Ja, es ist ein Vorteil dass nicht alles neu geladen werden muss. Objekte sollten dennoch nicht global sein.

Ich hatte bei einem Kunden das "Problem", dass ein einziges Modul nicht "sauber" implementiert war (Objekt war global) und dadurch Fehler bei einem User erzeugt wurden, die eigentlich von einem anderen User verursacht wurden. Es sind zwar seltene Fälle (je nach Konfig des Webservers), aber stell Dir mal eine Shopanwendung, in der Kundendaten (Kreditkartennummer,etc) in einem globalen Objekt gespeichert werden. Dann kann es passieren, dass ein User Deine Daten sieht, weil er gerade den Prozess bekommt, in dem Deine Daten in einem globalen Objekt gespeichert sind...

Quote
Gleichzeitig klingt das aber wieder nicht nach einem globalen Objekt (wg. $self) und dann wird es sowieso automatisch "gelöscht" (gelöscht stimmt ja nur bedingt) wenn es nicht mehr benötigt wird.


Vorsicht vor zirkulären Referenzen! Die können bei mod_perl ganz schnell mal Memory Leaks hervorrufen... Bei einem CGI-Skript (bei jedem Request alles neu laden und ausführen) wird am Ende des Skripts alles aufgeräumt. Bei mod_perl nicht unbedingt, da ja der ApacheChild weiterlebt...

Nur weil der Gültigkeitsbereich von $self verlassen wird, heißt das nicht, dass alles dahinter "zerstört" wird. Es kann ja sein, dass noch andere Variablen eine Referenz auf die Daten von $self haben - und wenn die "global" sind, dann ist das nicht vorteilhaft.

Quote

Mir stellt sich die Frage, warum es sinnvoll sein soll ein Objekt von Hand zu löschen, dass sowieso gelöscht wird? Und selbst wenn es relativ viel speicher belegt, wird das löschen nicht unbedingt einen folgenden Prozess beschleunigen, da das löschen schon Zeit kosten kann, eher verlangsamen.


Es hat keiner behauptet, dass das Löschen von Objekten etwas beschleunigt, aber es *kann* durchaus Sinn machen, das Objekt selbst zu "zerstören" und somit den Speicher (intern) freizugeben (wenn keine anderen Referenzen auf die Daten vorhanden sind). Zum einen kann man so zirkuläre Referenzen zerstören und zum anderen kann man extrem hohen Speicherverbrauch vermeiden.
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/
Struppi
 2007-11-14 13:34
#102400 #102400
User since
2006-02-17
628 Artikel
BenutzerIn
[Homepage]
user image
Danke, für die Ausführungen, das entspricht ungefähr dem wie ich das bisher verstanden habe.

Nur das Letzte will mir nicht so recht in den Sinn, vor allem im Kontext der Frage:
Quote
... aber es *kann* durchaus Sinn machen, das Objekt selbst zu "zerstören" und somit den Speicher (intern) freizugeben (wenn keine anderen Referenzen auf die Daten vorhanden sind). Zum einen kann man so zirkuläre Referenzen zerstören und zum anderen kann man extrem hohen Speicherverbrauch vermeiden.

Froschpopo hat in seine Frage ja $self eingebaut, was i.d.R. ja der Parameter ist, der auf das aktuelle Objekt zeigt, dass würde ich auf jeden Fall nie im Modul zerstören, sondern dann dort wo das Objekt verwendet wird.

Das Andere ist, wenn man denkt man hat ein Problem mit hängenden Referenzen, ist es da nicht günstiger explizit in DESTROY zu zerstören?
Oder sowas wie Scalar::Util::weaken zu verwenden?

Ich wundere mich halt über die Fragestellung, mir ist diese in 10 Jahren Perlprogrammierung noch nicht über den Weg gelaufen. Ich hatte schon Probleme mit tie, wo ich explizit mit undef Verbindungen trennen musste oder das DESTROY was sinnvolles machen muss, aber ein undef irgendwo im Code, weil ich dachte ich müßte Speicher sparen ist zumindest mir persönlich noch nicht über den Weg gelaufen.
renee
 2007-11-14 13:53
#102401 #102401
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Struppi+2007-11-14 12:34:52--
Danke, für die Ausführungen, das entspricht ungefähr dem wie ich das bisher verstanden habe.

Nur das Letzte will mir nicht so recht in den Sinn, vor allem im Kontext der Frage:
Quote
... aber es *kann* durchaus Sinn machen, das Objekt selbst zu "zerstören" und somit den Speicher (intern) freizugeben (wenn keine anderen Referenzen auf die Daten vorhanden sind). Zum einen kann man so zirkuläre Referenzen zerstören und zum anderen kann man extrem hohen Speicherverbrauch vermeiden.

Froschpopo hat in seine Frage ja $self eingebaut, was i.d.R. ja der Parameter ist, der auf das aktuelle Objekt zeigt, dass würde ich auf jeden Fall nie im Modul zerstören, sondern dann dort wo das Objekt verwendet wird.
das sehe ich genauso...

Quote
Das Andere ist, wenn man denkt man hat ein Problem mit hängenden Referenzen, ist es da nicht günstiger explizit in DESTROY zu zerstören?
Oder sowas wie Scalar::Util::weaken zu verwenden?


Habe ich noch nicht getestet was wie besser ist...

Quote
Ich wundere mich halt über die Fragestellung, mir ist diese in 10 Jahren Perlprogrammierung noch nicht über den Weg gelaufen. Ich hatte schon Probleme mit tie, wo ich explizit mit undef Verbindungen trennen musste oder das DESTROY was sinnvolles machen muss, aber ein undef irgendwo im Code, weil ich dachte ich müßte Speicher sparen ist zumindest mir persönlich noch nicht über den Weg gelaufen.


Das sollte in 99,9% der Fälle auch nicht notwendig sein.
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/
ptk
 2007-11-14 21:50
#102424 #102424
User since
2003-11-28
3645 Artikel
ModeratorIn
[default_avatar]
weaken hat den Vorteil, dass man sich als Nutzer einer Klasse nicht um das Aufräumen zu kümmern braucht. Das hat dann hoffentlich der Klassen-Autor an der richtigen Stelle eingebaut.

Zu mod_perl: es gibt eigentlich nicht viel zu renees Ausführungen hinzuzufügen. Ich rate ausdrücklich zu mod_perl, weil man damit am performantesten dynamische Webseiten ausliefern kann. Man muss aber auch gut tunen und darf keine groben Fehler machen. So werden Apache-Children mit mod_perl gerne 50-100MB groß. Wenn man dann die Standard-Apacheeinstellung der maximalen Child-Anzahl (AFAIR 200) nimmt, kann man bei Last leicht ins Swappen geraten und somit geht der ganze Performancevorteil verloren.

Auch steigt der Speicherverbrauch eines Apache-Childs *immer*. Das kann mehrere Gründe haben: memory leaks in den beteiligten Programmen (apache, mod_perl, perl, libc), die erwähnten zirkulären Referenzen, ineffiziente malloc-Implementationen (Fragmentierung des freien Speichers), oder einfach die Tatsache, dass immer mehr Perl-Code in den Prozess reingeladen wird... Da hilft es, wenn man MaxRequestsPerChild geschickt setzt: nicht zu niedrig, aber auch nicht zu hoch. Eventuell hilft es auch, wenn man einige verwendete Perl-Module per PerlModul schon im Root-Apache lädt und dann hofft, dass die Unix-Semantik beim forken (nur geänderte Speicherseiten müssen dupliziert werden) beim Niedrighalten des Speicherverbrauchs hilft.
pq
 2007-11-15 00:19
#102426 #102426
User since
2003-08-04
12208 Artikel
Admin1
[Homepage]
user image
zu dem, was ptk gesagt hat:
dass der speicherverbrauch eines childs stetig steigt, konnte ich auch mal nachvollziehen,
indem ich einen simplen handler gebaut habe, der nichts weiter tut, und dann per script requests
abgesetzt habe und die prozessgroesse verfolgt habe. allerdings ist das allein nicht unbedingt
tragisch, das kann mal selbst mal testen und gucken, nach wievielen requests der speicher
um wieviel gestiegen ist.
zu shared memory: um zu gucken, wieviel speicher denn noch geteilt ist nach dem forken,
kann man CPAN:Apache::SizeLimit verwenden, allerdings habe ich das vor einer weile etwas aus
den Augen verloren, da es mal durch ein debian-upgrade und eine damit verbundene
aenderung in der info ueber den speicherverbrauch nicht mehr korrekt funktionierte.

als ergaenzung zu der empfehlung, module moeglichst im root-prozess zu laden - man kann auch
viel sparen, indem man daten, die man nur liest, aber nicht schreibt, gleich zu anfang laedt.
beispielsweise eine uebersetzungstabelle o.ä. auch wenn man da mehrere MB hat - solange
es im root-prozess bleibt (und das bleibt es in der regel auch, wenn es eine eigenstaendige
variable ist, in der man keine daten veraendert), ist das ja wenig speicher.
Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live. -- Damian Conway in "Perl Best Practices"
lesen: Wiki:Wie frage ich & perlintro Wiki:brian's Leitfaden für jedes Perl-Problem
ptk
 2007-11-15 23:21
#102468 #102468
User since
2003-11-28
3645 Artikel
ModeratorIn
[default_avatar]
Leider kann bei perl auch das einfache Datenlesen dazu führen, dass Speicher alloziert wird:
Code: (dl )
1
2
3
4
5
use Devel::Peek;
$a = 123;
Dump $a;
$a."";
Dump $a;
ergibt
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
SV = IV(0x52c970) at 0x529a58
REFCNT = 1
FLAGS = (IOK,pIOK)
IV = 123
SV = PVIV(0x507848) at 0x529a58
REFCNT = 1
FLAGS = (IOK,POK,pIOK,pPOK)
IV = 123
PV = 0x508848 "123"\0
CUR = 3
LEN = 8

Beim ersten Dump gibt es noch kein PV, aber beim zweiten wird aus Performancegründen einer angelegt. Dazu genügt eine einfache Stringoperation, die die Variable nicht zu ändern braucht, vielleicht sogar schon ein einfaches print. Dadurch muss die gesamte Speicherseite dupliziert werden.
<< |< 1 2 3 >| >> 26 Einträge, 3 Seiten



View all threads created 2007-11-12 05:38.