PHP.mk документација

Собирање циклуси

Почист и полокален преглед на PHP референцата, со задржана структура од PHP.net и подобра читливост за примери, секции и белешки.

features.gc.collecting-cycles.php PHP.net прокси Преводот се освежува
Оригинал на PHP.net
Патека features.gc.collecting-cycles.php Локална патека за оваа страница.
Извор php.net/manual/en Оригиналниот HTML се реупотребува и локално се стилизира.
Режим Прокси + превод во позадина Кодовите, табелите и белешките остануваат читливи во истиот тек.
Собирање циклуси

Референца за `features.gc.collecting-cycles.php` со подобрена типографија и навигација.

features.gc.collecting-cycles.php

Собирање циклуси

Традиционално, механизмите за управување со меморија со броење на референци, како што претходно го користеше PHP, не успеваат да ги решат тековите на меморијата со циркуларни референци; сепак, од 5.3.0, PHP го имплементира синхрониот алгоритам од » Конкурентно собирање циклуси во системи со броење на референци документот кој го решава тој проблем.

Целосно објаснување за тоа како работи алгоритамот би било малку надвор од опсегот на овој дел, но основите се објаснети овде. Пред сè, мора да воспоставиме неколку основни правила. Ако рефбројот се зголеми, тој сè уште е во употреба и затоа не е ѓубре. Ако рефбројот се намали и достигне нула, zval може да се ослободи. Ова значи дека циклусите на ѓубре можат да се создадат само кога аргументот на рефбројот се намалува на вредност различна од нула. Второ, во циклус на ѓубре, можно е да се открие кои делови се ѓубре со проверка дали е можно да се намали нивниот рефброј за еден, а потоа да се провери кои од zval-овите имаат рефброј од нула.

Garbage collection algorithm

За да се избегне потребата да се повикува проверката на циклуси на ѓубре со секое можно намалување на рефбројот, алгоритамот наместо тоа ги става сите можни корени (zval-ови) во „баферот за корени“ (обележувајќи ги како „пурпурни“). Исто така, осигурува дека секој можен корен на ѓубре завршува во баферот само еднаш. Дури кога баферот за корени ќе се наполни, механизмот за собирање започнува за сите различни zval-ови внатре. Погледнете го чекор А на сликата погоре.

Во чекор Б, алгоритамот извршува длабинско пребарување на сите можни корени за да го намали за еден рефбројот на секој zval што ќе го најде, осигурувајќи се да не го намали рефбројот на истиот zval двапати (со обележување како „сиви“). Во чекор В, алгоритамот повторно извршува длабинско пребарување од секој корен јазол, за повторно да го провери рефбројот на секој zval. Ако открие дека рефбројот е нула, zval се обележува како „бел“ (син на сликата). Ако е поголем од нула, го враќа намалувањето на рефбројот за еден со длабинско пребарување од таа точка натаму, и тие повторно се обележуваат како „црни“. Во последниот чекор (Д), алгоритамот поминува низ баферот за корени отстранувајќи ги корените на zval од таму, и во меѓувреме, проверува кои zval-ови биле обележани како „бели“ во претходниот чекор. Секој zval обележан како „бел“ ќе биде ослободен.

Сега кога имате основно разбирање за тоа како работи алгоритамот, ќе погледнеме како ова се интегрира со PHP. Стандардно, собирачот на ѓубре на PHP е вклучен. Сепак, постои php.ini поставување што ви овозможува да го промените ова: zend.enable_gc.

Кога собирачот на ѓубре е вклучен, алгоритамот за пронаоѓање циклуси опишан погоре се извршува секогаш кога баферот за корени ќе се наполни. Баферот за корени има фиксна големина од 10.000 можни корени (иако можете да го промените со менување на GC_THRESHOLD_DEFAULT константата во Zend/zend_gc.c во изворниот код на PHP, и повторно компилирање на PHP). Кога собирачот на ѓубре е исклучен, алгоритамот за пронаоѓање циклуси никогаш нема да се изврши. Сепак, можните корени секогаш ќе бидат запишани во баферот за корени, без разлика дали механизмот за собирање ѓубре е активиран со оваа поставка за конфигурација.

Ако баферот за корени се наполни со можни корени додека механизмот за собирање ѓубре е исклучен, понатамошните можни корени едноставно нема да бидат запишани. Тие можни корени што не се запишани никогаш нема да бидат анализирани од алгоритамот. Ако беа дел од циклус на циркуларна референца, тие никогаш нема да бидат исчистени и би создале теков на меморија.

Причината зошто можните корени се запишуваат дури и ако механизмот е оневозможен е затоа што е побрзо да се запишат можните корени отколку да се проверува дали механизмот е вклучен секогаш кога може да се најде можен корен. Самиот механизам за собирање и анализа на ѓубре, сепак, може да одземе значително време.

Покрај менувањето на zend.enable_gc поставката за конфигурација, исто така е можно да се вклучи и исклучи механизмот за собирање ѓубре со повикување gc_enable() or gc_disable() односно. Повикувањето на тие функции има исто дејство како вклучување или исклучување на механизмот со поставката за конфигурација. Исто така е можно да се присили собирањето на циклуси дури и ако баферот за можни корени сè уште не е полн. За ова, можете да го користите gc_collect_cycles() функцијата. Оваа функција ќе врати колку циклуси биле собрани од алгоритамот.

Причината зад можноста за вклучување и исклучување на механизмот, и самостојно иницирање на собирање циклуси, е тоа што некои делови од вашата апликација може да бидат многу чувствителни на време. Во тие случаи, можеби нема да сакате да се активира механизмот за собирање ѓубре. Се разбира, со исклучување на собирањето ѓубре за одредени делови од вашата апликација, ризикувате да создадете текови на меморија бидејќи некои можни корени можеби нема да се вклопат во ограничениот бафер за корени. Затоа, веројатно е мудро да се повика gc_collect_cycles() непосредно пред да го повикате gc_disable() за да се ослободи меморијата што може да се изгуби преку можни корени што веќе се запишани во баферот за корени. Ова потоа остава празен бафер за да има повеќе простор за складирање на можни корени додека механизмот за собирање циклуси е исклучен.

Белешки од корисници 3 белешки

Далас
пред 7 години
After testing, breaking up memory intensive code into a separate function allows the garbage collection to work.

For example the original code was like:-
while(true){
   //do memory intensive code
}

can be turned into something like:-
function intensive($parameters){
   //do memory intensive code
}

while(true){
   intensive($parameters);
}
Yousha dot A at Hotmail dot com
пред 9 години
── Unused Objects ─── ─ In use Objects
↓                    ↓               ↓
 _____________________________________
 |□□□□□□□□□□□□□□□□□|██■■■■■■■■■■■■■■■■|
 |□□□□□□□□□□□□□□□□□|██■■■■■■■■■■■■■■■■|
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
          ▲                  ▲
     Unreferenced        Referenced
       Objects             Objects

█ Memory leak
Yousha dot A at Hotmail dot com
пред 10 години
Memory leak: meaning you keep a reference to it thus preventing the GC from collecting it.
На оваа страница

Автоматски outline од активната документација.

Насловите ќе се појават тука по вчитување.

Попрегледно читање

Примерите, changelog табелите и user notes се визуелно издвоени за да не се губат во долгата содржина.

Брз совет Користи го outline-от Скокни директно на главните секции од активната страница.
Извор Оригиналниот линк останува достапен Кога ти треба целосен upstream context, отвори го PHP.net во нов tab.