Ankündigung

Einklappen
Keine Ankündigung bisher.

Speicherhandling PHP

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Speicherhandling PHP

    Hallo zusammen,

    wir rätseln grade, wie sich PHP bei einem unset() hinsichtlich des Speichers verhält. Das Manual sagt, dass eine Variable gelöscht wird. Was nicht erwähnt wird ist, ob auch der Speicher deallokiert wird. Im Source-Code finde ich leider nichts über die unset()-Funktion, oder ich bin einfach zu blind.

    Hat jemand Rat?
    Viele Grüße,
    Dr.E.

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    1. Think about software design [B]before[/B] you start to write code!
    2. Discuss and review it together with [B]experts[/B]!
    3. Choose [B]good[/B] tools (-> [URL="http://adventure-php-framework.org/Seite/088-Why-APF"]Adventure PHP Framework (APF)[/URL][URL="http://adventure-php-framework.org"][/URL])!
    4. Write [I][B]clean and reusable[/B][/I] software only!
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

  • #2
    Re: Speicherhandling PHP

    Interessante Frage, scheint wirklich wieder freigegeben zu werden, wobei ein kleiner Overhead bleibt, zumindest wenn ich die Ausgabe richtig interpretiere:

    PHP-Code:
    <?php
    $before 
    memory_get_usage();
    $newVar = <<<TEST

    phpfriend.de - Die freundschaftliche PHP-Community
        
     SuchenSuchen  FAQFAQ  MitgliederlisteMitgliederliste  ImpressumImpressum
     ProfilProfil   PNDu hast keine neuen Nachrichten   Logout [ Zergling ]Logout [ Zergling ] 
        


    Speicherhandling PHP

     
    Neues Thema eröffnen   Neue Antwort erstellen      phpfriend.de Foren-Übersicht -> PHP - Anfänger   
    Vorheriges Thema anzeigen: 
    $_FILES Problem
    Nächstes Thema anzeigen: Es gibt keine neueren Themen in diesem Forum.  
    Autor   Nachricht
    dr.e.
    phpfriend.de-Moderator


    Anmeldedatum: 03.12.2004
    Beiträge: 870
    Wohnort: München
        
    Neuer BeitragVerfasst am: 24.10.2007, 17:43    Titel: Speicherhandling PHP  Antworten mit Zitat Beitrag bearbeiten oder löschen Beitrag löschen IP-Adresse zeigen
    Hallo zusammen,

    wir rätseln grade, wie sich PHP bei einem unset() hinsichtlich des Speichers verhält. Das Manual sagt, dass eine Variable gelöscht wird. Was nicht erwähnt wird ist, ob auch der Speicher deallokiert wird. Im Source-Code finde ich leider nichts über die unset()-Funktion, oder ich bin einfach zu blind.

    Hat jemand Rat?
    _________________
    Grüße,
    Dr.E.
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Searching for a php framework that rocks?
    Have a look at http://www.adventure-php-framework.org!
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Nach oben   
    Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen AddThis Social Bookmark Button       
    sofort antworten
                                

    Very Happy Smile Sad Surprised Shocked Confused Cool Laughing Mad Razz Embarassed Crying or Very sad Evil or Very Mad Twisted Evil Rolling Eyes Wink Exclamation Question Idea Arrow Neutral Mr. Green
    Optionen
    Letzte Nachricht beantworten
    Signatur anhängen (Signatur kann im Profil geändert werden)
    Benachrichtigt mich, wenn eine Antwort geschrieben wurde

     
    Beiträge der letzten Zeit anzeigen:   
    Neues Thema eröffnen   Neue Antwort erstellen      phpfriend.de Foren-Übersicht -> PHP - Anfänger   Alle Zeiten sind GMT + 1 Stunde
    Seite 1 von 1
    Bei Antworten zu diesem Thema benachrichtigen

    Thema löschen Thema verschieben Thema sperren Thema teilen      
    Gehe zu:  
    Du kannst Beiträge in dieses Forum schreiben.
    Du kannst auf Beiträge in diesem Forum antworten.
    Du kannst deine Beiträge in diesem Forum bearbeiten.
    Du kannst deine Beiträge in diesem Forum löschen.
    Du kannst an Umfragen in diesem Forum mitmachen.
    Du kannst dieses Forum moderieren.



    Creative Commons License
    Dieser Inhalt ist unter einer Creative Commons-Lizenz lizenziert.


    Powered by phpBB © 2001, 2005 phpBB Group


    Home | Forum | Tutorials | 1&1 Webhosting | 1&1 DSL | Site Map | Impressum

    phpfriend.de wird unterstützt von gmfmedien

    TEST;
    $between memory_get_usage();
    unset(
    $newVar);
    $afterwards memory_get_usage();

    var_dump($before0$between $before$afterwards $before);
    ?>
    Code:
    int(62096) int(0) int(2904) int(160)

    Edit 1:
    Hm andererseits, wenn man memory_get_usage(TRUE) verwendet, kommt
    Code:
    int(262144) int(0) int(0) int(0)
    raus, was die ganze Erkenntnis wieder in Frage stellt.
    Was ist schon $real_usage?!


    Edit 2: Andererseits im Beispiel auf memory_get_usage() wird auch unset() angeführt, wenn das nicht nur ein ahnungsloser Doku-Sklave geschrieben hat, könnte man das so interpretieren, dass unset() tatsächlich den Speicher freigibt. Ich denke PHP ist weit genug entwickelt, das zu tun, es wäre zumindest sinnvoll.

    Kommentar


    • #3
      die unset funktion befindet sich, wie die meisten language constructs, in zend/zend_compile.c.

      da ich ziemlich wenig ahnung von c habe, musst du den rest allerdings selbst rausfinden.....

      unset:

      Code:
      void zend_do_unset(znode *variable TSRMLS_DC)
      {
      	zend_op *last_op;
      
      	zend_check_writable_variable(variable);
      
      	if (variable->op_type == IS_CV) {
      		zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
      		opline->opcode = ZEND_UNSET_VAR;
      		opline->op1.op_type = IS_CONST;
      		opline->op1.u.constant.type = IS_STRING;
      		opline->op1.u.constant.value.str.len = CG(active_op_array)->vars[variable->u.var].name_len;
      		opline->op1.u.constant.value.str.val = estrdup(CG(active_op_array)->vars[variable->u.var].name);
      		SET_UNUSED(opline->op2);
      		opline->op2.u.EA.type = ZEND_FETCH_LOCAL;
      		SET_UNUSED(opline->result);
      	} else {
      		last_op = &CG(active_op_array)->opcodes[get_next_op_number(CG(active_op_array))-1];
      
      		switch (last_op->opcode) {
      			case ZEND_FETCH_UNSET:
      				last_op->opcode = ZEND_UNSET_VAR;
      				break;
      			case ZEND_FETCH_DIM_UNSET:
      				last_op->opcode = ZEND_UNSET_DIM;
      				break;
      			case ZEND_FETCH_OBJ_UNSET:
      				last_op->opcode = ZEND_UNSET_OBJ;
      				break;
      
      		}
      	}
      }
      über zend_opcode.c gehts dann, so wie ich das sehe, in zend_hash.c:

      Code:
      ZEND_API void zend_hash_clean(HashTable *ht)
      {
      	Bucket *p, *q;
      
      	IS_CONSISTENT(ht);
      
      	SET_INCONSISTENT(HT_CLEANING);
      
      	p = ht->pListHead;
      	while (p != NULL) {
      		q = p;
      		p = p->pListNext;
      		if (ht->pDestructor) {
      			ht->pDestructor(q->pData);
      		}
      		if (q->pData != &q->pDataPtr) {
      			pefree(q->pData, ht->persistent);
      		}
      		pefree(q, ht->persistent);
      	}
      	memset(ht->arBuckets, 0, ht->nTableSize*sizeof(Bucket *));
      	ht->pListHead = NULL;
      	ht->pListTail = NULL;
      	ht->nNumOfElements = 0;
      	ht->nNextFreeElement = 0;
      	ht->pInternalPointer = NULL;
      
      	SET_INCONSISTENT(HT_OK);
      }
      naja bei zend.com gibts noch: http://www.zend.com/apidoc/zend.layo...management.php
      [B]PHP4?!?[/B]>>>[B]Aktuelle[/B] PHP Version: [B]5.2.11 || 5.3.0
      [URL="http://en.opensuse.org/Factory/News"]Suse 11.2 *vorfreude*[/URL]
      [/B]

      Kommentar


      • #4
        Danke erstmal. Das Codesnipet hatte ich beim grepen auch schon gesehen, aber weitergeklickt. So wie ich den Code verstehe wird schon ein pefree() aufgerufen, allerdings verwirren mich die Konstrukte

        Code:
           memset(ht->arBuckets, 0, ht->nTableSize*sizeof(Bucket *));
           ht->pListHead = NULL;
           ht->pListTail = NULL;
           ht->nNumOfElements = 0;
           ht->nNextFreeElement = 0;
           ht->pInternalPointer = NULL;
        ein wenig, weil da irgendwas auf NULL gesetzt wird. So tief bin ich dann aber leider nicht im C-Code von PHP bewandert um zu verstehen, wie die Structs hier Einfluss auf die Runtime haben.

        Eine Recherche auf zend.com hat mich leider auch nicht weitergebracht. Allerdings scheint "ht" der interne Hashtable von Variablen und Objekten, die während der Laufzeit verwendet werden zu sein.

        Für weitere Anregungen / Infomationen bin ich dankbar!
        Viele Grüße,
        Dr.E.

        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        1. Think about software design [B]before[/B] you start to write code!
        2. Discuss and review it together with [B]experts[/B]!
        3. Choose [B]good[/B] tools (-> [URL="http://adventure-php-framework.org/Seite/088-Why-APF"]Adventure PHP Framework (APF)[/URL][URL="http://adventure-php-framework.org"][/URL])!
        4. Write [I][B]clean and reusable[/B][/I] software only!
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

        Kommentar


        • #5
          interessant ist noch> http://www.hardened-php.net/hphp/zen...erability.html
          [B]PHP4?!?[/B]>>>[B]Aktuelle[/B] PHP Version: [B]5.2.11 || 5.3.0
          [URL="http://en.opensuse.org/Factory/News"]Suse 11.2 *vorfreude*[/URL]
          [/B]

          Kommentar


          • #6
            Interessante Information zu den Hashtables (und dem PHP-Bug ). Danke!
            Viele Grüße,
            Dr.E.

            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            1. Think about software design [B]before[/B] you start to write code!
            2. Discuss and review it together with [B]experts[/B]!
            3. Choose [B]good[/B] tools (-> [URL="http://adventure-php-framework.org/Seite/088-Why-APF"]Adventure PHP Framework (APF)[/URL][URL="http://adventure-php-framework.org"][/URL])!
            4. Write [I][B]clean and reusable[/B][/I] software only!
            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

            Kommentar


            • #7
              und was gefunden?

              was mich noch interessiern würde, wäre ob variablen innerhalb von funktionen nach ende der funktion aus dem speicher gelöscht würden....
              [B]PHP4?!?[/B]>>>[B]Aktuelle[/B] PHP Version: [B]5.2.11 || 5.3.0
              [URL="http://en.opensuse.org/Factory/News"]Suse 11.2 *vorfreude*[/URL]
              [/B]

              Kommentar


              • #8
                Hallo brian johnson,

                es werden explizit die Referenzen aus dem PHP-Hash-Table gelöscht. Rein vom Verständnis sollte damit auch Speicher freigegeben werden.
                Viele Grüße,
                Dr.E.

                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                1. Think about software design [B]before[/B] you start to write code!
                2. Discuss and review it together with [B]experts[/B]!
                3. Choose [B]good[/B] tools (-> [URL="http://adventure-php-framework.org/Seite/088-Why-APF"]Adventure PHP Framework (APF)[/URL][URL="http://adventure-php-framework.org"][/URL])!
                4. Write [I][B]clean and reusable[/B][/I] software only!
                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

                Kommentar


                • #9
                  Zitat von dr.e.
                  Hallo brian johnson,

                  es werden explizit die Referenzen aus dem PHP-Hash-Table gelöscht. Rein vom Verständnis sollte damit auch Speicher freigegeben werden.
                  eigentlich schon ja....gut danke!
                  [B]PHP4?!?[/B]>>>[B]Aktuelle[/B] PHP Version: [B]5.2.11 || 5.3.0
                  [URL="http://en.opensuse.org/Factory/News"]Suse 11.2 *vorfreude*[/URL]
                  [/B]

                  Kommentar


                  • #10
                    TEST;
                    $between = memory_get_usage();
                    unset($newVar);
                    $afterwards = memory_get_usage();

                    var_dump($before, 0, $between - $before, $afterwards - $before);
                    ?>[/php]

                    Code:
                    int(62096) int(0) int(2904) int(160)

                    Edit 1:
                    Hm andererseits, wenn man memory_get_usage(TRUE) verwendet, kommt
                    Code:
                    int(262144) int(0) int(0) int(0)
                    raus, was die ganze Erkenntnis wieder in Frage stellt.
                    Was ist schon $real_usage?!
                    Ich finde im Netz leider nichts zu dem Parameter $real_usage, daher diese alte Thread.

                    Ich dachte es könnte der Peak sein, allerdings stimmt das ja auch nicht, weil bei peak kann man ja auch $real_usage unterstützt.

                    Welchen Wert sollte man bei der Auswertung seiner Scripte heranziehen. $real_usage oder ohne?

                    Gruß
                    meine PHP Scripte

                    Kommentar


                    • #11
                      Mhh ich bin mir zwar nicht ganz sicher aber ich meine das wird so gehandhabt:

                      Wird eine Variable mit unset() gelöscht wird sie nur freigegeben. Der Speicher bleibt trotzdem noch belegt bis der GarbageCollector ihn wieder freigibt. Dies passiert entweder wenn der CPU mal Zeit hat oder PHP keinen Speicher mehr für die Skriptausführung hat.
                      Um eine Variable wirklich zu löschen (Speicher frei zu geben) muss man $var = null; setzen. Allerdings braucht dass dann auch mehr Rechenzeit.

                      Aber wie gesagt das ist nicht unbedingt richtig, keine Ahnung woher ich das gehört hab

                      Kommentar


                      • #12
                        Das ist mir schon klar, allerdings verstehe ich nicht den Unterschied bei der memory-Abfrage.

                        $var = null funktioniert meiner Ansicht nicht. Allerdings habe ich es auch noch nie getestet.
                        meine PHP Scripte

                        Kommentar


                        • #13
                          Ok ich weiß jetzt was der Paramter bedeutet. Und zwar belegt PHP den Speicher immer blockweise. D.h. wenn man z.B. 900 KByte verbraucht hat, hat man in Wirklichkeit 1024 KByte verbraucht. Zumindest ist das auf meinem System jetzt so gewesen.

                          Wenn man nun den Speicherverbrauch optimieren will, sollte man memory_get_usage() ohne true benutzen. Am Ende des Prozesses sollte man sich aber noch mal memory_get_peak_usage() und memory_get_peak_usage(true) ausgeben lassen und versuchen den nächst geringeren Schritt zu erreichen. Wenn das nicht möglich ist, kann man sich die Optimierung gleich sparen, weil PHP wie gesagt einen gesamten Block belegt.
                          meine PHP Scripte

                          Kommentar


                          • #14
                            Zitat von Flor1an Beitrag anzeigen
                            Mhh ich bin mir zwar nicht ganz sicher aber ich meine das wird so gehandhabt:

                            Wird eine Variable mit unset() gelöscht wird sie nur freigegeben. Der Speicher bleibt trotzdem noch belegt bis der GarbageCollector ihn wieder freigibt. Dies passiert entweder wenn der CPU mal Zeit hat oder PHP keinen Speicher mehr für die Skriptausführung hat.
                            Um eine Variable wirklich zu löschen (Speicher frei zu geben) muss man $var = null; setzen. Allerdings braucht dass dann auch mehr Rechenzeit.

                            Aber wie gesagt das ist nicht unbedingt richtig, keine Ahnung woher ich das gehört hab
                            problematischer wird das ganze, wenn man php per CGI am laufen hat. dann läuft ein PHP prozess der zwar intern speicher freigibt, aber eben nicht an das OS (bzw. erst bei "notwendigkeit"). memory managment eben.

                            und - wie du richtig sagst - erst wenn der GC anläuft gibt PHP speicher zurück. alles eine sache der optimierung, es ist wesentlich schneller einen systemaufruf zu sparen (vgl. Ring) und alles selber zu managen.

                            Wenn das nicht möglich ist, kann man sich die Optimierung gleich sparen, weil PHP wie gesagt einen gesamten Block belegt.
                            da php ein memory limit hat, stimmt das so nicht.
                            [B]PHP4?!?[/B]>>>[B]Aktuelle[/B] PHP Version: [B]5.2.11 || 5.3.0
                            [URL="http://en.opensuse.org/Factory/News"]Suse 11.2 *vorfreude*[/URL]
                            [/B]

                            Kommentar


                            • #15
                              Du hast mich falsch verstanden. Ich meine, wenn man innerhalb eines 256er Blocks festhängt, also von 250kb auf 50kb optimieren könnte, so würde es im gesamten nichts bringen, da man immer noch einen gesamten 256er Block belegt.

                              Hier z.B. zwei Peak-Werte:
                              RAM: 10.0092 MB last - 14.314 MB peak - 14.5 MB real peak
                              Wie man sieht, ist real peak größer. Es ist also der gesamte Block gefüllt.

                              Ich will damit nur klar machen, dass es sich nicht immer lohnt unset() zu benutzen (also nicht für jeden Kleinkram), denn der Aufruf befreit zwar den RAM, belastet dafür aber wieder die Performance und am Ende schafft man vermutlich nicht mal einen gesamten Block.
                              meine PHP Scripte

                              Kommentar

                              Lädt...
                              X