[php5] Objecten / reference count

Pagina: 1
Acties:

  • BoomSmurf
  • Registratie: Maart 2003
  • Laatst online: 13-06-2025
Stel ik doe dit:

PHP:
1
2
3
$a = new MyObj;
$b = $a;
$a = null;


Dan bestaat deze instantie van MyObj nog in $b (de destructor wordt niet aangeroepen, etc)

Nu heb ik een class die een record uit de database bevat. Instanties hiervan wilde ik eigenlijk bijhouden in een 'pool'. Komt er een nieuw object bij dan wordt deze bovenaan de pool geplaatst. Wordt er een oud object gebruikt (1 van de functies of velden wordt gebruikt), dan verschuift deze ook naar boven in de pool. Als je even wat bezig bent heb je natuurlijk heel veel objecten, dus wil ik het object onderaan de pool (langst niet gebruikt) weggooien. Als deze informatie weer nodig is wordt die automagisch weer uit de database getrokken.

Ik wil echter natuurlijk geen object weggooien dat nog ergens gebruikt wordt, dus mag ik alleen het langst niet gebruikte object weggooien die ook een reference count van 1 heeft (want de pool houd het object natuurlijk ook bij). De grote vraag is, hoe kan ik (het pool object) nu weten of een ander object een reference count van 1 heeft? (Kon het zelf niet vinden). Het kan natuurlijk met zo'n constructie (dit werkt natuurlijk niet echt zo in mijn code)

PHP:
1
2
3
$a = new MyObj; 
$b = $a->UpYourReferenceCountAndReturnYoSelf();
...


Maar hier wil ik eigenlijk niet aan.

Iemand ideeen?

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 22-03 18:12
In dit geval zit er nog wel een instantie van MyObj in $b. Dit omdat je bij zo'n toewijzing aan $b een kopie van $a maakt, die wel naar hetzelfde object verwijst. Volgens mij zit het zo wel anders:
PHP:
1
2
3
$a = new MyObj();
$b = &$a;
$b = null;

Als ik het goed heb is $a nu ook gelijk aan null.

Edit:

Het is niet helemaal wat je vraagt lees ik nu. Je zult toch speciale methods moeten maken om dit bij te houden. Je zou ook de pooling aan een apart object over kunnen laten.

Waarom zou je dit eigenlijk willen doen? Per request haal je toch maar enkele objecten op die bij het eindigen van het script weer verdwijnen. Of je bent bezig met een script dat wel blijft draaien?

[ Voor 44% gewijzigd door Michali op 21-06-2005 15:44 ]

Noushka's Magnificent Dream | Unity


  • aex351
  • Registratie: Juni 2005
  • Laatst online: 01:41

aex351

I am the one

Michali schreef op dinsdag 21 juni 2005 @ 15:36:
In dit geval zit er nog wel een instantie van MyObj in $b. Dit omdat je bij zo'n toewijzing aan $b een kopie van $a maakt, die wel naar hetzelfde object verwijst. Volgens mij zit het zo wel anders:
PHP:
1
2
3
$a = new MyObj();
$b = &$a;
$b = null;

Als ik het goed heb is $a nu ook gelijk aan null.

Edit:

Het is niet helemaal wat je vraagt lees ik nu. Je zult toch speciale methods moeten maken om dit bij te houden. Je zou ook de pooling aan een apart object over kunnen laten.

Waarom zou je dit eigenlijk willen doen? Per request haal je toch maar enkele objecten op die bij het eindigen van het script weer verdwijnen. Of je bent bezig met een script dat wel blijft draaien?
Ik denk niet dat $a nu ook NULL is, omdat $a al referentie is meegegeven aan $b. wat dus inhoud dat je met $b alles kan doen over verder gaan waar $a gebleven is, maar het beinvloed $a niet.

Maar als je $a de waarde Null meegeeft is $b ook Null

[ Voor 4% gewijzigd door aex351 op 21-06-2005 16:03 ]

< dit stukje webruimte is te huur >


  • BoomSmurf
  • Registratie: Maart 2003
  • Laatst online: 13-06-2025
Michali schreef op dinsdag 21 juni 2005 @ 15:36:
In dit geval zit er nog wel een instantie van MyObj in $b. Dit omdat je bij zo'n toewijzing aan $b een kopie van $a maakt, die wel naar hetzelfde object verwijst. Volgens mij zit het zo wel anders:
PHP:
1
2
3
$a = new MyObj();
$b = &$a;
$b = null;

Als ik het goed heb is $a nu ook gelijk aan null.
Jawel, maar als ik alles op die manier ga aliassen, dan verdwijnt het object ook meteen uit mijn pool.
Edit:

Het is niet helemaal wat je vraagt lees ik nu. Je zult toch speciale methods moeten maken om dit bij te houden. Je zou ook de pooling aan een apart object over kunnen laten.

Waarom zou je dit eigenlijk willen doen? Per request haal je toch maar enkele objecten op die bij het eindigen van het script weer verdwijnen. Of je bent bezig met een script dat wel blijft draaien?
Nja het hele probleem komt een beetje voort uit mijn drang voor automagischheid. Stel je voor dat ik een 'klantHenk' object heb (1 record dus van onze klant Henk). Nu verander ik bevoorbeeld zijn achternaam. Dit moet natuurlijk naar de database. Ik kan wel de save(); functie aanroepen die het naar de database schrijft maar het liefst zou ik dit niet doen en de destructor dit gewoon laten doen wanneer het object destroyed wordt. Maarrr stel ik doe iets met klantHenk, roep een functie aan (die stiekum ook iets met klantHenk doet) en doe er dan weer iets mee. Dan wil ik natuurlijk dat die functie dezelfde klantHenk gebruikt als de 'omliggende' code, dus dat object moet bijgehouden worden (vandaar de pool) en deze moet gebruikt worden, niet de waarde die op dat moment in de database staat (zou je dit niet doen, zou je database ook veel meer verkeer te verwerken hebben). Maar ik wil natuurlijk ook weer niet alle objecten tot in de oneindigheid bij gaan houden (zullen er vaak niet zo veel zijn, maar het kunnen er natuurlijk WEL veel zijn, wat funest is voor je load). Dit is maar één type van het voorbeeld, maar uiteindelijk zou het hele systeem (wat natuurlijk veel meer is dan ik nu allemaal vertel) geheugen consumptie laag houden en niet zo veel db-verkeer veroorzaken (wel een iets hogere cpu load maar goed). Ik hoop dat je een beetje begrijpt waar ik op doel :)

  • BoomSmurf
  • Registratie: Maart 2003
  • Laatst online: 13-06-2025
Nja omdat het allemaal niet schijnt te kunnen heb ik in mijn basisklasse zelf maar reference counting geimplementeerd. Alle objecten moeten dan voortaan wel met $a = addRef($obj) geinstantieerd en met removeRef($a) gereleased worden maar goed (met uitzondering van de ene keer dat 'new' gebruikt wordt maar dat gebeurd achter de schermen in het framework).