[php] register_shutdown_function in class

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • JeRa
  • Registratie: Juni 2003
  • Laatst online: 30-04 10:28

JeRa

Authentic

Topicstarter
Aangezien ik geen toegang heb tot memory_get_usage() dacht ik gebruik te maken van een handmatige destructor in een class om erachter te komen of een object wel verwijderd wordt. Zie deze code:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class test
{
    function &test()
    {
        register_shutdown_function(array(&$this, '_test'));
        return $this;
    }

    function _test()
    {
        echo "_test()\n";
    }
}

echo "\n1\n";

$obj = &new test();

echo "2\n";

unset($obj);

echo "3\n";


Dit levert als resultaat:

1
2
3
_this()

Maar ik wil dus dit zien:

1
2
_this()
3

Zodat ik zeker weet dat door het verwijderen van de reference naar het object, het geheugen vrij komt. Hoe kan ik dit doen?

Ik maak gebruik van PHP 4.3.4 (in PHP5 zou ik al direct toegang hebben tot 'normale' destructors).

[ Voor 12% gewijzigd door JeRa op 06-02-2004 15:53 ]

ifconfig eth0 down


Acties:
  • 0 Henk 'm!

  • beetle71
  • Registratie: Februari 2003
  • Laatst online: 09-09 15:24
Huh? register_shutdown_function is de functie die wordt aangeroepen als het php-script beeindigd wordt. Waarom wil je dan nog geheugen vrijmaken? Dat wordt toch al gedaan doordat het script afsluit.. :?

edit:

Waarom doe je overigens dit ?!?
PHP:
1
$obj = &new test();


$obj is toch automatisch al een referentie naar die class. Ik bedoel waarom moet je een instance van een class nog een reference geven?

[ Voor 39% gewijzigd door beetle71 op 06-02-2004 18:27 ]


Acties:
  • 0 Henk 'm!

  • JeRa
  • Registratie: Juni 2003
  • Laatst online: 30-04 10:28

JeRa

Authentic

Topicstarter
beetle71 schreef op 06 februari 2004 @ 18:23:
Huh? register_shutdown_function is de functie die wordt aangeroepen als het php-script beeindigd wordt. Waarom wil je dan nog geheugen vrijmaken? Dat wordt toch al gedaan doordat het script afsluit.. :?
In voorbeelden (zoals hier) gebruiken ze register_shutdown_function() om een destructor na te bootsen. Ik wil geen geheugen vrijmaken, ik wil zeker weten dat het object vernietigd is, en dus geen geheugen meer gebruikt. Ik wil dit weten omdat ik bezig ben met een ingewikkeld node-systeem waar vele duizenden nodes in zitten, en het dus cruciaal is dat er niet ergens een memory leak zit :)
Waarom doe je overigens dit ?!?
PHP:
1
$obj = &new test();


$obj is toch automatisch al een referentie naar die class. Ik bedoel waarom moet je een instance van een class nog een reference geven?
Op die manier kopieert ie de nieuwe instance (new test()) niet naar $obj, maar maakt hij een directe reference naar het nieuwe object. Zie ook deze pagina.

ifconfig eth0 down


Acties:
  • 0 Henk 'm!

  • Terranca
  • Registratie: April 2000
  • Laatst online: 18-09 18:25
Naar mijn weten returned een "new" operator in PHP altijd by reference, dus die & kan inderdaad vergeten worden.

Overigens is de register_shutdown_function in PHP alleen bedoeld om bepaalde code uit te voeren, zoals bijvoorbeeld in een log schrijven, of mysql connecties af te sluiten, het is echter niet de bedoeling er output mee te geven! Aangezien bij het afsluiten van de pagina de output buffer al geflushed wordt voordat de hij de destructor kan aanroepen. (dit is niet altijd het geval, waarom jij dus ook wel output krijgt, maar reken erop dat er PHP configuraties zijn waarbij dit niet het geval is!)

Blijkbaar wordt jouw object pas verwijdert aan het einde van de pagina, als alle output is geweest, en sinds er geen "delete" operator is in PHP, zou ik zo snel geen manier weten om die "_test()" output voor de 3 te laten weergeven (ik zou overigens niet weten waarom je dit zou willen doen? Desctructors horen alleen op te schonen).

[ Voor 13% gewijzigd door Terranca op 06-02-2004 19:46 . Reden: Verkeerd gebold :P ]


Acties:
  • 0 Henk 'm!

  • JeRa
  • Registratie: Juni 2003
  • Laatst online: 30-04 10:28

JeRa

Authentic

Topicstarter
Bedankt voor je uitleg :)
Terranca schreef op 06 februari 2004 @ 19:41:
Naar mijn weten returned een "new" operator in PHP altijd by reference, dus die & kan inderdaad vergeten worden.
Van de laatste link van mijn laatste reactie:
Apparently there is no difference, but in fact there is a very significant one: $bar1 and $globalref[0] are _NOT_ referenced, they are NOT the same variable. This is because "new" does not return a reference by default, instead it returns a copy.
Een new-operator levert natuurlijk een reference, dat kan ook niet anders. Maar dat is wel een reference naar een kopie ;)
Blijkbaar wordt jouw object pas verwijdert aan het einde van de pagina, als alle output is geweest, en sinds er geen "delete" operator is in PHP, zou ik zo snel geen manier weten om die "_test()" output voor de 3 te laten weergeven (ik zou overigens niet weten waarom je dit zou willen doen? Desctructors horen alleen op te schonen).
Ik wilde met die destructor controleren of het object daadwerkelijk werd verwijderd. Het node-systeem is vrij ingewikkeld en ik wilde er zeker van zijn dat er nergens meer references naar één van die nodes stonden, en er dus kostbaar geheugen verloren gaat :)

ifconfig eth0 down


Acties:
  • 0 Henk 'm!

  • Terranca
  • Registratie: April 2000
  • Laatst online: 18-09 18:25
JeRa schreef op 06 februari 2004 @ 21:04:
Ik wilde met die destructor controleren of het object daadwerkelijk werd verwijderd. Het node-systeem is vrij ingewikkeld en ik wilde er zeker van zijn dat er nergens meer references naar één van die nodes stonden, en er dus kostbaar geheugen verloren gaat :)
Als je gewoon netjes gebruikt maakt van PHP en je code niet heel erg smerig maakt kan je er wel op rekenen dat alle objecten keurig worden weggemietered na het eindigen van een script. Bugs als deze zullen ze bij het PHP team wel grondig hebben aangepakt, mocht je toch nog een gegronde reden hebben om PHP te verdenken van memory leaks, kan je uiteraard een nieuwe update proberen (als het je eigen server is, anders eisen van je provider ;)) en desnoods af en toe de webserver herstarten.

Die & in je newis trouwens wel voor erg specifieke situatie's, zoals inderdaad op die pagina staat, voor speciale eigenschappen in constructors. Zie ook iets onder jouw quote in hetzelfde document op PHP.net:
Note: There is no performance loss (since PHP 4 and up use reference counting) returning copies instead of references. On the contrary it is most often better to simply work with copies instead of references, because creating references takes some time where creating copies virtually takes no time (unless none of them is a large array or object and one of them gets changed and the other(s) one(s) subsequently, then it would be wise to use references to change them all concurrently).
Je kan nml ook gewoon de constructor niks laten returnen en alleen de regel: register_shutdown_function(array(&$this, '_test')); in die functie zetten, en de class aanroepen met: $test = new test;
Snap niet waarom je het nieuwe object weer by reference returned :P
Maar goed, dit zijn allemaal performance tweakjes, wat trouwens wel zorgt voor nettere code.
Pagina: 1