首頁  >  文章  >  後端開發  >  精選3題,帶你了解PHP的垃圾回收機制! !

精選3題,帶你了解PHP的垃圾回收機制! !

青灯夜游
青灯夜游轉載
2021-06-04 19:25:483271瀏覽

這篇文章跟大家分享關於PHP垃圾回收機制的高階面試題,並帶大家深入了解PHP垃圾回收機制。有一定的參考價值,有需要的朋友可以參考一下,希望對大家有幫助。

精選3題,帶你了解PHP的垃圾回收機制! !

ps:本篇內容包含精選面試題目與知識篇。

PHP面試題關於PHP的垃圾回收機制,PHP的垃圾回收機制引用計數(reference counting) GC 機制,PHP可以自動進行記憶體管理,清除不需要的對象,PHP面試題分享PHP關於垃圾回收機制的面試題目:

推薦學習:《PHP影片教學

##面試題篇


介紹PHP的垃圾回收機制

    PHP使用了參考計數(reference counting)GC機制,同時使用根緩衝區機制,當php發現有存在循環引用的zval時,就會把其投入到根緩衝區,當根緩衝區達到配置文件中的指定數量後,就會進行垃圾回收,以此解決循環引用導致的記憶體洩漏問題。
  • 1. 如果引用計數減少到零,所在變數容器將被清除(free),不屬於垃圾;
2. 如果一個zval的引用計數減少後還大於0,那麼它就會進入垃圾週期。其次,在一個垃圾週期中,透過檢查引用計數是否減1,並且檢查哪些變數容器的引用次數是零,來發現哪一部分是垃圾。

每個對像都內含一個引用計數器refcount,每個reference連接到對象,計數器加1。當reference離開生存空間或被設為 NULL,計數器會減1。當某個物件的參考計數器為零時,PHP知道你將不再需要使用這個對象,釋放其所佔的記憶體空間。 下列關於PHP垃圾回收的說法,錯誤的是?

A、開啟/關閉垃圾回收機制可以透過修改php配置實作

B、可以在程式中使用gc_enable() 和 gc_disable()開啟和關閉。

C、PHP中的垃圾回收機制,會大幅提升系統效能。

D、開啟垃圾回收機制後,針對記憶體外洩的情況,可以節省大量的記憶體空間,但由於垃圾回收演算法運作耗費時間,開啟垃圾回收演算法會增加腳本的執行時間。


參考答案:C

答案解析:PHP中的垃圾回收機制,僅在循環回收演算法確實運行時會有時間消耗上的增加。但是在平常的(更小的)腳本中應根本沒有效能影響。

php垃圾回收機制的說法錯誤的是?

A、在一個垃圾週期中,透過檢查引用計數是否減1,並且檢查哪些變數容器的引用次數是零,來發現哪部分是垃圾

#B、可以透過呼叫gc_enable() 和gc_disable()函數來開啟和關閉垃圾回收機制

C、透過清理未使用的變數來節省記憶體的佔用

D、php程式碼執行完畢後會自動執行垃圾回收,所以不需要手動執行垃圾回收


參考答案:D

答案解析:php一段程式碼有可能要長時間執行,但若此期間有未引用的變數的話,就會佔用記憶體的空間,導致運行緩慢等問題

知識篇


一、概念

#垃圾回收是多數程式語言中都帶有的記憶體管理機制。與非託管性語言相反:C, C 和 Objective C,使用者需要手動收集內存,帶有 GC 機制的語言:Java, javaScript 和 PHP 可以自動管理記憶體。

垃圾回收機制(gc)顧名思義,就是廢棄物重利用的意思,是一種動態儲存分配的方案。它會自動釋放程式不再需要的已分配的記憶體區塊。垃圾回收機制可以讓程式設計師不必過度關心程式記憶體分配,從而將更多的精力投入業務邏輯。

在現在的流行各種語言當中,垃圾回收機制是新一代語言所共有的特徵,如Python、PHP、C#、Ruby等都使用了垃圾回收機制。 二、PHP垃圾回收機制

####1、在PHP5.3版本之前,使用的垃圾回收機制是單純的「引用計數」。 ###

Что такое подсчет ссылок?
Поскольку PHP написан на C, в C есть нечто, называемое структурой. Наши переменные PHP хранятся в C таким образом.
Каждая переменная PHP существует в контейнере под названием zval.Контейнер zval, помимо имени и значения переменной, также включает в себя два байта дополнительной информации:
ا Один из них называется "is_ref" и представляет собой логическое значение, используемое для указания того, принадлежит ли эта переменная набору ссылок. С помощью этого байта мы можем отличить обычные переменные от ссылочных переменных в PHP.
• Второй дополнительный байт — это «refcount», который используется для указания количества переменных, указывающих на этот контейнер.

То есть:

① Каждому объекту памяти назначается счетчик.Когда на объект памяти ссылается переменная, счетчик равен 1;

② Когда переменная После удаления ссылки (после выполнения unset()), счётчик равен -1;

③ Когда счётчик = 0, это указывает, что объект памяти не используется, объект памяти уничтожается, и сбор мусора завершается.

И PHP освободит содержимое, занятое этим процессом/потоком, после окончания жизненного цикла.Этот метод определяет, что PHP не нужно учитывать слишком большие утечки памяти на ранней стадии.

Но когда два или более объектов ссылаются друг на друга, образуя кольцо, счетчик объекта памяти не будет уменьшен до 0; в это время эта группа объектов памяти больше не полезна, но не может перерабатываться, что приводит к утечкам памяти.

Начиная с версии php5.3 использован новый механизм сборки мусора.На основе подсчета ссылок реализован сложный алгоритм обнаружения существования колец ссылок в объектах памяти во избежание утечек памяти.

  • 2.С развитием PHP, увеличением числа разработчиков PHP и расширением сферы деятельности, которую он несет, в PHP5.3 были представлены более полный механизм сборки мусора и новая сборка мусора. Механизм решает проблему утечек эталонной памяти, которая не может обрабатывать циклы.

Как говорится в официальной документации: каждая переменная php существует в контейнере переменных под названием «zval». Контейнер переменных zval содержит, помимо типа и значения переменной, два байта дополнительной информации. Первый — «is_ref», который представляет собой логическое значение, используемое для определения принадлежности этой переменной к набору ссылок. С помощью этого байта механизм PHP может отличать обычные переменные от ссылочных переменных.Поскольку PHP позволяет пользователям использовать собственные ссылки с помощью &, в контейнере переменных zval также имеется внутренний механизм подсчета ссылок для оптимизации использования памяти.

Второй дополнительный байт — это «refcount», который используется для указания количества переменных (также называемых символами), указывающих на этот контейнер переменных zval. Все символы существуют в таблице символов, и каждый символ имеет область действия.

Официальные документы говорят, что вы можете использовать Xdebug для проверки счетчика ссылок:

<?php $a = "new string";
$c = $b = $a;
xdebug_debug_zval( &#39;a&#39; );
unset( $b, $c );
xdebug_debug_zval( &#39;a&#39; );
?>

Приведенная выше процедура выведет:

a: (refcount=3, is_ref=0)='new string'
a: (refcount=1, is_ref=0)='new string'

Примечание: начиная с NTS-версии PHP7, приведенные выше ссылки на подпрограмму больше не будут учитываться, т.е. c=c= c=b=Счетчик ссылок a после $a равен также 1. В частности, классификация следующая:

В PHP 7 zvals может иметь подсчет ссылок или нет. В структуре zval есть флаг, определяющий это.

① Для переменных типа null, bool, int и double счетчик refcount никогда не будет учитываться;

② Для объектов и типов ресурсов счетчик refcount соответствует php5;

③ Для строк переменные без кавычек называются «фактическими строками». Эти строки, на которые имеются ссылки, дедуплицируются (т. е. имеется только одна вставленная строка с определенным содержимым) и гарантированно существуют в течение всего времени запроса, поэтому для них нет необходимости использовать подсчет ссылок; если используется opcache, эти строки будут жить в общей памяти, и в этом случае вы не можете использовать подсчет ссылок (поскольку наш механизм подсчета ссылок не является атомарным);

④Для массивов переменные, на которые нет ссылок, называются «Неизменяемым массивом». Подсчет самого массива соответствует PHP5, но подсчет каждой пары ключ-значение в массиве основан на трех предыдущих правилах (то есть, если это строка, она не учитывается); если используется opcache , константный литерал массива в коде будет Преобразовать в неизменяемый массив.

Опять же, они живут в общей памяти, поэтому подсчет ссылок использовать нельзя.

Наш демонстрационный пример выглядит следующим образом:

<?php echo &#39;测试字符串引用计数&#39;;
$a = "new string";
$b = $a;
xdebug_debug_zval( &#39;a&#39; );
unset( $b);
xdebug_debug_zval( &#39;a&#39; );
$b = &$a;
xdebug_debug_zval( &#39;a&#39; );
echo &#39;测试数组引用计数&#39;;
$c = array(&#39;a&#39;,&#39;b&#39;);
xdebug_debug_zval( &#39;c&#39; );
$d = $c;
xdebug_debug_zval( &#39;c&#39; );
$c[2]=&#39;c&#39;;
xdebug_debug_zval( &#39;c&#39; );
echo &#39;测试int型计数&#39;;
$e = 1;
xdebug_debug_zval( &#39;e&#39; );

Вывод, который вы видите, следующий:

精選3題,帶你了解PHP的垃圾回收機制! !

3 Цикл переработки

###По умолчанию механизм сбора мусора PHP включен, и в php.ini есть настройка, позволяющая его изменить: zend.enable_gc. ###

Когда механизм сбора мусора включен, алгоритм определит, что всякий раз, когда корневой буфер заполнен, будет выполняться циклический поиск. Область корневого кэша имеет фиксированный размер, значение по умолчанию — 10 000. Это значение можно изменить, изменив константу GC_ROOT_BUFFER_MAX_ENTRIES в файле исходного кода PHP Zend/zend_gc.c и затем перекомпилировав PHP. При выключенной сборке мусора алгоритм поиска цикла никогда не выполняется, однако корень всегда будет существовать в корневом буфере, независимо от того, активирована ли сборка мусора в конфигурации.

Помимо изменения конфигурации zend.enable_gc, вы также можете включать и выключать механизм сборки мусора при запуске php, вызывая функции gc_enable() и gc_disable() соответственно. Вызов этих функций имеет тот же эффект, что и изменение элементов конфигурации для включения или выключения механизма сборки мусора. Возможность принудительного периодического сбора данных, даже если корневой буфер не заполнен. Для этой цели вы можете вызвать функцию gc_collect_cycles(). Эта функция вернет количество циклов, переработанных с использованием этого алгоритма.

Причина, по которой вы разрешаете включать и выключать сбор мусора и разрешать автономную инициализацию, заключается в том, что некоторые части вашего приложения могут быть чувствительными ко времени. В этом случае вы, вероятно, не захотите использовать сбор мусора. Конечно, отключение сборки мусора для определенных частей вашего приложения сопряжено с риском возможных утечек памяти, поскольку некоторые возможные корни могут не поместиться в ограниченный корневой буфер.

Поэтому непосредственно перед вызовом функции gc_disable() для освобождения памяти, возможно, будет разумно сначала вызвать функцию gc_collect_cycles(). Поскольку это очистит все возможные корни, которые были сохранены в корневом буфере, тогда, когда механизм сборки мусора выключен, можно оставить пустой буфер, чтобы иметь больше места для хранения возможных корней.

#4. Влияние на производительность

##1. Экономия памяти

Прежде всего, вся причина реализации механизм сбора мусора Цель состоит в том, чтобы сэкономить использование памяти путем очистки переменных, на которые имеются циклические ссылки, после выполнения предварительных условий. При выполнении PHP сбор мусора выполняется после заполнения корневого буфера или вызова функции gc_collect_cycles().

2. Увеличение времени выполнения

Вторая область, в которой сбор мусора влияет на производительность, — это время, необходимое для освобождения утекшей памяти.

Обычно механизм сбора мусора в PHP увеличивает затраты времени только тогда, когда фактически работает алгоритм переработки. Но в обычных (меньших) сценариях никакого влияния на производительность быть не должно.

3. Когда в обычных скриптах работает механизм повторного использования, экономия памяти позволит одновременно запускать больше таких скриптов на вашем сервере. Потому что общий объем используемой памяти не достиг верхнего предела.

Это преимущество особенно очевидно в долго выполняющихся сценариях, таких как долго выполняющиеся наборы тестов или сценарии демонов. В то же время для приложений-скриптов, которые обычно работают дольше, чем веб-скрипты, новый механизм сборки мусора должен существенно изменить устоявшееся мнение о том, что утечки памяти трудно устранить.

Наконец, я желаю всем вам пройти собеседование и получить понравившееся предложение.

Для получения дополнительной информации о программировании посетите: Введение в программирование! !

以上是精選3題,帶你了解PHP的垃圾回收機制! !的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:juejin.cn。如有侵權,請聯絡admin@php.cn刪除