Итерация ассоциативного массива без использования цикла foreach и утечка памяти - PullRequest
4 голосов
/ 22 марта 2012

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

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

Первый вопрос - правильны ли мои рассуждения?

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

Один из способов, который я могу придумать, - использовать array_walk(), другой - использовать комбинацию функций next() и key() в цикле for. Какой подход не оставит меня с утечками памяти?

Я выполню некоторые тесты и опубликую результаты после того, как я закончу.

Вторичная проблема заключается в том, как обращаться с итерируемыми объектами, но это на потом.

РЕДАКТИРОВАТЬ 1 : результаты моих тестов несколько отличаются, поэтому я опубликую что-то новое после некоторых исследований.

1 Ответ

1 голос
/ 28 марта 2012

Использование next () и key () не даст вам утечек памяти, которые делает foreach.Foreach создает «внутреннюю» копию вашего массива, и эта копия является проблемой утечки памяти.Использование next () и key () не создает копию - тогда вы работаете с исходными данными.

Еще одно предложение, как решить эту проблему, заключается в использовании array_keys () следующим образом:

$keys = array_keys($assoc_array);
for ($keyindex = 0; $keyindex < count($keys); $keyindex++) {
    $key = $keys[$keyindex];
    $val = $assoc_array[$key];

    /* Now you have $key and $val. */

}

Однако я считаю, что ваше предложение с помощью next () и key () будет наиболее эффективным - и, вероятно, даст вам самый красивый код!:)

...