php.de

Zurück   php.de > Webentwicklung > PHP-Fortgeschrittene

PHP-Fortgeschrittene Arbeiten mit PHP ohne Einschränkungen

Antwort
 
LinkBack Themen-Optionen Thema bewerten
Alt 02.11.2011, 15:26  
Benutzer
 
Registriert seit: 16.06.2004
Beiträge: 81
PHP-Kenntnisse:
Fortgeschritten
RcRaCk2k
RcRaCk2k eine Nachricht über ICQ schicken RcRaCk2k eine Nachricht über MSN schicken RcRaCk2k eine Nachricht über Yahoo! schicken
Standard refcount PHP Memory-Handling Event on RefCount === 1

Hallo Leute!

Seit einiger Zeit entwickeln wir Anwendungen, die komplett OOP basierend sind. Das sieht so aus:

Wir haben eine Datenbank (MySQL) und bilden die Tabellen in Klassen ab. Die Klasse lautet dann z.B. STRUCT_xyz und beinhaltet lediglich die Felder der Tabelle, wie z.B. public $id; public $name;

Darüber gibt es einen OOP-Teil, der die Strukturen als SINGLETON verwaltet, wie z.B. BACKEND_xyz. Dort befindet sich ein Caching-Array private static $structs;, wo sich alle geladenen Datenbank-Inhalte der Struktur "xyz" befinden.

Das Ganze sieht nun so aus:
Code:
$data = BACKEND_xyz::get( 12817 );
# refcount = 2
echo $data->name();
$data->set_name('Max Mustermann');
echo $data->name();
$data->commit();
unset( $data );
# refcount =1
Die Struct von "xyz" wird in der BACKEND_xyz in der privaten statischen Variable BACKEND_xyz::$structs vorgehalten, damit mehrere Funktionen mit diesem Datensatz arbeiten können.

Wenn Ich also obiges Beispiel ausführe so hat die STRUCT_xyz einen refcount von 2.

Wenn ich einen UNSET mache, dann ist der refcount gleich 1. In diesem Falle könnte ich die Struktur komplett aus dem Speicher entladen indem ich aus der statischen privaten Variable BACKEND_xyz::$structs den Eintrag entfernen würde. Der GC würde dann beim nächsten Lauf den Speicher freigeben.

Mein Problem ist nun, wie finde ich heraus, dass es für meine STRUCT nur noch einen einzigen REFCOUNT gibt um den Speicher freigeben zu können?
RcRaCk2k ist offline   Mit Zitat antworten
Sponsor Mitteilung
PHP Code Flüsterer

Registriert seit: 21.08.2005
Beiträge: 4682
PHP-Kenntnisse:
Fortgeschritten

Alt 02.11.2011, 15:55  
Erfahrener Benutzer
 
Benutzerbild von tr0y
 
Registriert seit: 26.07.2010
Beiträge: 4.874
PHP-Kenntnisse:
Fortgeschritten
tr0y ist ein wunderbarer Anblicktr0y ist ein wunderbarer Anblicktr0y ist ein wunderbarer Anblicktr0y ist ein wunderbarer Anblicktr0y ist ein wunderbarer Anblicktr0y ist ein wunderbarer Anblicktr0y ist ein wunderbarer Anblicktr0y ist ein wunderbarer Anblick
tr0y eine Nachricht über MSN schicken
Standard

garnicht, weil unnötig, php räumt am ende des scripts auf. Wird nur nötig wenn du solange objekte in den RAM bastelst bis dir das Limit um die Ohren fliegt, was ich bei dem beschriebenen Chaos gerne glaube.

http://de.wikipedia.org/wiki/Entwurfsmuster

Deine "Tabellen in Klassen abgebildet" nennt man kleinlaut Models, aber ich häng mich da aus dem Fenster weil das warscheinlich Container mit allerhand Aufgaben sein werden, nur kein Model ^^

P.S.: Bei deinem Nick krieg ich fast die Kriese.
__________________
Lasse mir ohne Anwendung von Gewalt Dinge schenken, Amazon weiß darüber bald mehr.
tr0y ist offline   Mit Zitat antworten
Alt 02.11.2011, 18:13  
hts
Erfahrener Benutzer
 
Registriert seit: 07.09.2010
Beiträge: 722
PHP-Kenntnisse:
Fortgeschritten
hts befindet sich auf einem aufstrebenden Ast
Standard

Mit der Xdebug-Erweiterung könntest du die Anzahl der Referenzen ermitteln: http://php.net/manual/de/features.gc...ing-basics.php
,wobei auf einem Produktivserver eher ungewöhlich.

Aber du könntest doch in der Backend-Klasse die Referenzen mit verwalten (Aufrufe von get() der entsprechenden ID) und dann anstelle von unset( $data ); einfach BACKEND_xyz::unset($data); aufrufen? Mit __destruct() funktioniert es leider nicht.
hts ist offline   Mit Zitat antworten
Alt 02.11.2011, 23:22  
Moderator und Wett-König
 
Benutzerbild von dr.e.
 
Registriert seit: 21.05.2008
Beiträge: 3.657
PHP-Kenntnisse:
Fortgeschritten
dr.e. ist ein Lichtblickdr.e. ist ein Lichtblickdr.e. ist ein Lichtblickdr.e. ist ein Lichtblickdr.e. ist ein Lichtblickdr.e. ist ein Lichtblick
dr.e. eine Nachricht über Skype™ schicken
Standard

Zitat:
Deine "Tabellen in Klassen abgebildet" nennt man kleinlaut Models, aber ich häng mich da aus dem Fenster weil das warscheinlich Container mit allerhand Aufgaben sein werden, nur kein Model ^^
Vielleicht fangen wir mal beim Thema "row data gateway" oder "table data gateway" an. Ob sich das Ergebnis nun "Model" oder "DTO" nennt, hängt noch von weiteren Faktoren ab.
__________________
Viele Grüße,
Dr.E.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1. Think about software design before you start to write code!
2. Discuss and review it together with experts!
3. Choose good tools (-> Adventure PHP Framework (APF))!
4. Write clean and reusable software only!
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
dr.e. ist offline   Mit Zitat antworten
Alt 04.11.2011, 20:46  
Benutzer
 
Registriert seit: 16.06.2004
Beiträge: 81
PHP-Kenntnisse:
Fortgeschritten
RcRaCk2k
RcRaCk2k eine Nachricht über ICQ schicken RcRaCk2k eine Nachricht über MSN schicken RcRaCk2k eine Nachricht über Yahoo! schicken
Standard

Sorry, dass ich erst jetzt antworte.

Ich dachte mir schon fast, dass es nicht geht. Über Xdebug hab ich schon gelesen, dass es "gehen" soll, aber das ist ja alles andere als sauber.

Ich weis nicht. Vielleicht schreibe ich eine PHP Erweiterung, die bei unset von Variablen die User-Defined-Class mit einer __unset( $refcount ) Funktion called. Dann wäre die Sache gegessen.

Werde mal mit dem PHP-Dev-Team sprechen - vielleicht nehmen die die Erweiterung ja auf.

@tr0y: Natürlich räumt PHP GC am Ende auf, jedoch hab ich - wie du schon richtig erkannt hast - ein Problem, nämlich möchte ich einen Export in XML machen und dabei auf meine "Models" zurückgreifen. Jedoch haut es mir bei einigen vielen Datensätzen den Memory-Limit um die Ohren.

@hts: Japp ich verwende eine manuelle Unload-Funktion, denn beim Export weis ich ja, dass ich die Infos nicht mehr brauche und daher einen Unload machen kann. Wenn nun jedoch nicht so erfahrene Programmierer an unserem Programm-Code rumprogrammieren, dann denken die sicherlich nicht an das Memory-Management und irgendwann funktioniert das Programm anschließend ab einer bestimmten Datenmenge nicht mehr.

@dr.e. DTO ist unsere Klasse keines Falles. Zwar haben wir Querreferenzierungen in den Klassen sprich user_id() = Datenbankfeld user() = Klassenreferenz auf BACKEND_user. So kann man - wie du dir sicherlich denken kannst - einfacher mit Referenzen agieren.

Vielen Dank schon mal für eure Hilfe.
Sobald ich einen PHP-Patch / eine Erweiterung - muss mal kucken, wie es funktioniert - geschrieben habe, die die virtuelle Funktion __unset( $refcount ) aufruft, dann lade ich hier gern den Patch hoch - denke, dass diese Methode vielleicht noch mehr Leute brauchen könnten.
RcRaCk2k ist offline   Mit Zitat antworten
Alt 07.11.2011, 10:15  
Erfahrener Benutzer
 
Registriert seit: 02.09.2009
Beiträge: 1.019
PHP-Kenntnisse:
Fortgeschritten
mquadrat befindet sich auf einem aufstrebenden Ast
Standard

Du kommst ans Memory-Limit? In jedem Request?!
__________________
Wir suchen PHP Entwickler (Vollzeit) im Raum Darmstadt / Rhein-Main. Infos via E-Mail mueller@new-frontiers.de
mquadrat ist offline   Mit Zitat antworten
Alt 12.11.2011, 19:40  
Benutzer
 
Registriert seit: 16.06.2004
Beiträge: 81
PHP-Kenntnisse:
Fortgeschritten
RcRaCk2k
RcRaCk2k eine Nachricht über ICQ schicken RcRaCk2k eine Nachricht über MSN schicken RcRaCk2k eine Nachricht über Yahoo! schicken
Standard

Nein das natürlich nicht. Im normalen Umfeld funktioniert das problemlos, da arbeite ich ja allerhöchstens bei normalen VIEWS mit nur einem Datensatz * 10 Tabellen, in Listen mit maximal 50 Datensätzen * 10 Tabellen (je nach Konfiguration der Liste "RPP").

Wo ich Probleme habe ist dann, wenn ich einen Export aller Daten in ein XML mache, bzw. eine XMLRPC-Suchanfrage mit z.B. 500 Ergebnissen aus 10 Tabellen liefere.

Im XML-Export und sonstigen Exports kann ich mir aktuell nur so behelfen, meine eigene Funktion ->close() zu verwenden und danach einen UNSET im Caller und im Cache zu machen. Bei ->get_instance() zähle ich den usage-counter hoch und bei close() wieder runter. Wenn der Usage-Counter auf auf 0 ist, schmeiße ich die Instanz aus meinem Cache.

Jedoch programmieren über 45 Leute an dem Code und wenn da Schlamper dabei sind, dann gibts halt das Problem, dass alles für eine bestimmte Zeit gut geht und irgendwann das Problem mit dem Speicherüberlauf auftritt.

Wir hatten den Fall schon und das ist für alle Parteien unangenehm. Über eine Zentrale Stelle mit __unreference() oder einem sonstigem Keyword, wäre das einfach schöner und sauberer gelöst, da nicht unbedingt auch ein UNSET von nöten ist, wenn man die Daten in einer Funktion verwendet, die pro Zeile genutzt wird.
RcRaCk2k ist offline   Mit Zitat antworten
Antwort


Themen-Optionen
Thema bewerten
Thema bewerten:

Forumregeln
Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are an
Gehe zu

Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
Event Handling System NecroniX Software-Design 13 09.08.2011 11:31
imagecreatefromjpeg() "Allowed memory size exhausted" peter silie PHP Tipps 2010 17 04.05.2011 14:25

Besucher kamen über folgende Suchanfragen bei Google auf diese Seite
refcount, memory-handling, refcount springt immer auf 2

Alle Zeitangaben in WEZ +2. Es ist jetzt 22:43 Uhr.




Powered by vBulletin® Version 3.7.2 (Deutsch)
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.2.0
Aprilia-Forum, Aquaristik-Forum, Liebeskummer-Forum, Zierfisch-Forum, Geizkragen-Forum