Heim  >  Artikel  >  Backend-Entwicklung  >  Detaillierte Erläuterung des PHP7-Garbage-Collection-Mechanismus (mit vollständigem Flussdiagramm der GC-Verarbeitung)

Detaillierte Erläuterung des PHP7-Garbage-Collection-Mechanismus (mit vollständigem Flussdiagramm der GC-Verarbeitung)

藏色散人
藏色散人nach vorne
2020-08-25 17:49:294957Durchsuche

Garbage Collection:

wird als GC bezeichnet. Wie der Name schon sagt, bedeutet es die Wiederverwendung von Abfällen.
Bevor wir über den Garbage-Collection-Mechanismus sprechen, gehen wir zunächst auf Speicherlecks ein.

Empfohlenes Tutorial: „PHP7

Speicherleck:

Erklärung eines grafischen Bildes eines großen Gottes:

Bedeutet wahrscheinlich, dass man sich um ein Stück Land bewirbt, eine Weile kackt und nach der Fertigstellung nicht aufräumt Kacken, dann gilt dieses Stück Land als verschwendet. Je mehr das Land genutzt wird, desto weniger wird es am Ende voller Scheiße sein. Denken Sie letztendlich daran, es nach Gebrauch zurückzugeben. Bis zu einem gewissen Grad wird der Müllsammelmechanismus zum Abwischen des Hinterns verwendet.

C-Sprach-Garbage-Collection-Mechanismus:

Wenn Sie die C-Sprache verwendet haben, können Sie den Speicher über malloc oder calloc beantragen. Nachdem Sie diesen Speicher aufgebraucht haben, vergessen Sie nicht, ihn mit der kostenlosen Funktion freizugeben. Dies ist eine manuelle Garbage Collection, die im Allgemeinen von Meistern auf diese Weise verwendet wird.

Was ist der automatische Garbage-Collection-Mechanismus von PHP?

Lassen Sie uns zunächst über diese Frage nachdenken. Wir alle wissen, dass PHP in der Sprache C implementiert ist. Überlegen Sie, wie Sie die Sprache C verwenden, um Statistiken zu implementieren und eine Variable freizugeben. Wie implementiert die C-Sprache eine Variable? Von der Deklaration bis zum Ende, wenn niemand sie verwendet, wird der von der Variablen belegte Speicher freigegeben (wurde durch Müll gesammelt).

PHP verfügt über zwei Kernalgorithmen für die Speicherverwaltung:
Einer ist die Referenzzählung und der andere ist Copy-on-Write.

Beim Deklarieren einer PHP-Variablen generiert die C-Sprache unten eine Struktur (Struktur) namens zval wie folgt:

zval {
string "a" //变量的名字是a
value zend_value //变量的值,联合体
type string //变量是字符串类型
}

zval struct structure

(1) Speichern Sie den Variablennamen von PHP $a
(2) Den Variablentyp von PHP $a
(3) Die zend_value-Vereinigung der PHP-Variablen $a

Wenn Sie der -Variablen einen Wert zuweisen, z. B. „Hallo Welt“, generiert die C-Sprache unten eine Union (Union) namens zend_value

zend_value {
string "hello world" //值的内容
refcount 1 //引用计数
}

zend_values ​​Union (Union)

(1) Speichern Sie den Wert von die Variable von PHP $a Hallo Welt

(2) Notieren Sie die Anzahl der Verweise auf die PHP-Variable $a

Sehen Sie sich die zval-Strukturstruktur und zend_value an. Wenn der Interviewer Sie fragt, warum die PHP-Variable die Zeichenfolge „123“ speichern kann. und die Nummer 123, Sie wissen, was zu tun ist. Haben Sie darauf geantwortet? Der entscheidende Punkt ist, dass zval den Typ der Variablen 123 enthält, der Typ ist string, und wenn es sich um eine Ganzzahl 123 handelt, ist der Typ von zval int und der Wert ist 123.

Was ist Referenzzählung?

Aktuelle Code-Analyse der PHP-Variablenreferenzanzahl

$a = 'hello,world';
echo xdebug_debug_zval( 'a');//refcount=1
$b = $a;
echo xdebug_debug_zval( 'a'); //$b引用$a,故变量a,refcount=2
$c = $a;
echo xdebug_debug_zval( 'a'); //$c引用$a,故变量a,refcount=3
unset( $c );
echo xdebug_debug_zval( 'a');//删除了$c的引用,故变量a,refcount=2

Laufende Ergebnisse:

a:

(refcount=1, is_ref=0)string 'hello,world' (length=11)
a:
(refcount=2 , is_ref=0)string 'hello,world' (length=11)
a:
(refcount=3, is_ref=0)string 'hello,world' (length=11)
a:
(refcount=2, is_ref = 0)string 'hello,world' (Länge=11)

Was ist Kopieren?

$a = 'hello';
$b = $a;//$a赋值给$b的时候,$a的值并没有真的复制了一份
echo xdebug_debug_zval( 'a');//$a的引用计数为2
$a = 'world';//当我们修改$a的值为123的时候,这个时候就不得已进行复制,避免$b的值和$a的一样
echo xdebug_debug_zval( 'a');///$a的引用计数为1

Operationsergebnisse:

a:

(refcount=2, is_ref=0)string 'hello' (length=5)
a:
(refcount=1, is_ref=0)string 'world' (length= 5)

Wenn Sie $a $b zuweisen, wird der Wert von $a nicht wirklich kopiert. Dies ist äußerst respektlos gegenüber dem Speicher und äußerst respektlos gegenüber der Zeitkomplexität. Respektieren Sie nur $ b zum Wert von $a. Dies nennt man schnell und wirtschaftlich. Wann findet also tatsächlich die Replikation statt? Das heißt, wenn wir den Wert von $a auf 123 ändern, müssen wir ihn zu diesem Zeitpunkt kopieren, um zu verhindern, dass der Wert von $b mit $a übereinstimmt.

Zwei wichtige Punkte werden anhand einfacher Fälle klar erklärt: Referenzzählung und Copy-on-Write.

Garbage-Collection-Mechanismus:

Wenn ein zval nicht festgelegt ist oder wenn ihm eine Funktion (also eine lokale Variable) und viele andere Stellen ausgehen, werden zval und zend_value getrennt Dieses Verhalten Zu diesem Zeitpunkt Was die Zend-Engine erkennen muss, ist, ob der Refcount von zend_value 0 ist. Wenn er 0 ist, wird der Inhalt direkt KO freigegeben. Wenn die Neuzählung von zend_value nicht 0 ist, kann der Wert nicht freigegeben werden. Dies bedeutet jedoch nicht, dass zend_value unschuldig ist, da zend_value möglicherweise immer noch Müll ist.

(1) Wenn der Refcount der PHP-Variablen $a=0 ist, wird die Variable $a im Müll gesammelt.

(2) Wenn der Refcount der PHP-Variablen $a>0 ist, kann auch die Variable $a berücksichtigt werden Müll

Was für eine Situation führt dazu, dass der Refcount von zend_value nicht 0 ist, dieser zend_value aber Müll ist?

$arr = [ 1 ];
$arr[] = &$arr;
unset( $arr );

这种情况下,zend_value不会能释放,但也不能放过它,不然一定会产生内存泄漏,所以这会儿zend_value会被扔到一个叫做垃圾回收堆中,然后zend引擎会依次对垃圾回收堆中的这些zend_value进行二次检测,检测是不是由于上述两种情况造成的refcount为1但是自身却确实没有人再用了,如果一旦确定是上述两种情况造成的,那么就会将zend_value彻底抹掉释放内存。

垃圾回收发生在什么时候?

有些同学可能有疑问,就是php不是运行一次就销毁了吗,我要gc有何用?并不是的,首先当一次fpm运行完毕后,最后一定还有gc的,这个销毁就是gc;其次是,内存都是即用即释放的,而不是攒着非得到最后,你想想一个典型的场景,你的控制器里的某个方法里用了一个函数,函数需要一个巨大的数组参数,然后函数还需要修改这个巨大的数组参数,你们应该是函数的运行范围里面修改这个数组,所以此时会发生写时拷贝了,当函数运行完毕后,就得赶紧释放掉这块儿内存以供给其他进程使用,而不是非得等到本地fpm request彻底完成后才销毁。

(1)fpm运行完毕后,最后一定会gc的
(2)运行过程中,也会gc的,内存都是即用即释放的,而不是攒着非得到最后gc

GC处理完整流程图

 

Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung des PHP7-Garbage-Collection-Mechanismus (mit vollständigem Flussdiagramm der GC-Verarbeitung). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:csdn.net. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen