За последние 24 часа нас посетили 30566 программистов и 1801 робот. Сейчас ищет 981 программист ...

Утечка памяти

Тема в разделе "Прочие вопросы по PHP", создана пользователем <?=RPG?>, 20 фев 2011.

  1. <?=RPG?>

    <?=RPG?> Активный пользователь

    С нами с:
    19 ноя 2010
    Сообщения:
    451
    Симпатии:
    0
    Пишу тестилку РНР-скриптов. Скрипт достаточно прост: генерится мега-большой РНР файл, где тестируемая операция повторяется несколько тыс раз. Затем тот файл инклюдится главным скриптом, раз 50. И вот что я заметил. Тестов много, все разные, но на некоторых РНР течёт как сито: память жрётся от каждого include мегабайтами!

    Например, файл, в котором $a['a']=1;$a['c']=1;$a['b']=1; повторяется 10 тыс раз не приводит к утечке памяти, а конструкция $a[1]=1;$a[4]=1;$a[2]=1; привела к неконтролируемому выделению памяти (по мегабайту за итерацию) что в конечном итоге привело к скоропостижной кончине процесса.

    Вопрос прост: что за ...?

    С большим трудом я только нашел причину утечек памяти - это всего навсего два теста из ~30.

    P.S. Утечки памяти наблюдаются и в процессе работы скрипта, но течет по 10-20 килобайт, а не мегабайтами.
     
  2. titch

    titch Активный пользователь

    С нами с:
    18 дек 2010
    Сообщения:
    847
    Симпатии:
    0
    хм... было бы интересно посмотреть и на другие тесты
     
  3. <?=RPG?>

    <?=RPG?> Активный пользователь

    С нами с:
    19 ноя 2010
    Сообщения:
    451
    Симпатии:
    0
    Вот на нем все летит к чертям:

    ;РНР-файл, который нужно выполнить до теста, но не учитывать время его выполнения (обычно там просто <?php)
    head = "<?php $arr=array_fill(0, 100000, 1);"
    ;РНР-файл, который нужно выполнить после теста, но не учитывать время его выполнения
    end = ""
    ;перечисление самих тестов
    test[] = "$x = count($arr);"
    test_info[] = "$x = count($arr);"
    test[] = "$x = sizeof($arr);"
    test_info[] = "$x = sizeof($arr);"

    count или sizeof повторяется 10000 раз и пишется в файл РНР, затем этот файл инклюдится 50 раз. На каждый инклюд жрется туча памяти, хотя и была чистка переменных и вообще он инклюдится внутри функции, следовательно вся память функции должна быть очищена. Если число итераций поставить не 10000 а 10, то память не расходуется.

    когда я инклюдил файлы по одному разу это не было так заметно. 50 раз файл дергается чтобы посчитать дисперсию.
     
  4. <?=RPG?>

    <?=RPG?> Активный пользователь

    С нами с:
    19 ноя 2010
    Сообщения:
    451
    Симпатии:
    0
    Новый симптом: вырубаешь php-акслератор и всё как по маслу.
     
  5. titch

    titch Активный пользователь

    С нами с:
    18 дек 2010
    Сообщения:
    847
    Симпатии:
    0
    многие оптимизирующие обфускаторы и код-оптимизаторы умеют сглаживать такие места (просто переписывают этот кусок кода иначе). так что бага в php скорее всего есть. если использовать оптимизатор, то тест уже никак нельзя назвать чистым
     
  6. <?=RPG?>

    <?=RPG?> Активный пользователь

    С нами с:
    19 ноя 2010
    Сообщения:
    451
    Симпатии:
    0
    Дело как раз в том, что БЕЗ акселератора всё нормально. Я запускаю тест с акселератором и без: так можно узнать, какие моменты он сглаживает. Надо отметить, включение оптимизатора не сильно влияет на общие результаты теста.
     
  7. iliavlad

    iliavlad Активный пользователь

    С нами с:
    24 янв 2009
    Сообщения:
    1.689
    Симпатии:
    4
    а ты не искал - может это уже описанная проблема?
     
  8. <?=RPG?>

    <?=RPG?> Активный пользователь

    С нами с:
    19 ноя 2010
    Сообщения:
    451
    Симпатии:
    0
    Нет, я не думаю что есть ещё один псих, насилующий РНР иклюдом в цикле 500 раз подряд:)
    Я решил проблему заменив временно include на system('php '.$file)