За последние 24 часа нас посетили 18549 программистов и 1600 роботов. Сейчас ищут 952 программиста ...

Out of memory при потребление памяти >1,5 ГБ

Тема в разделе "Прочие вопросы по PHP", создана пользователем bimcom, 25 май 2009.

  1. bimcom

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

    С нами с:
    25 май 2009
    Сообщения:
    10
    Симпатии:
    0
    Здраствуйте!
    Подскажите с чем может быть связана ошибка Out of memory когда скрипту требуется памяти >1,5ГБ?
    (нужно обработать массив данных, который и загружается весть в память)
    В PHP.ini
    memory_limit = 2500M
    Ошибка вылетает на PHP Version 5.2.4
    с начала подумал что возможно глюк сборки - скачал последнюю PHP Version 5.2.9-2, в ней уже ошибка Out of memory не появляется, но скрипт не завершается, а все время выполняется, открыв диспетчер задач (все крутится на WinXP SP3 + Denwer, опетаривки 3,25ГБ, в boot.ini дописан ключ 3GB) видно что процес потредляет, потредляет память, как уровень потреьления памяти доходит до 1514 МБ - объем потребляемой памяти идет на спад до 0, потом процесс похоже перезапускается и снова так покругу пока не остановлю выполнение процесса.
     
  2. [vs]

    [vs] Суперстар
    Команда форума Модератор

    С нами с:
    27 сен 2007
    Сообщения:
    10.559
    Симпатии:
    632
    Не нужно, разделите на части. Какой кстати текст ошибки?
     
  3. bimcom

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

    С нами с:
    25 май 2009
    Сообщения:
    10
    Симпатии:
    0
    Fatal error: Out of memory (allocated 1587544064) (tried to allocate 393216 bytes)

    разделение данных на части невозможно, использование БД тоже(скорость очень низкая).
     
  4. [vs]

    [vs] Суперстар
    Команда форума Модератор

    С нами с:
    27 сен 2007
    Сообщения:
    10.559
    Симпатии:
    632
    Без кода ничего определенного сказать нельзя, угадывать неинтересно.
     
  5. bimcom

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

    С нами с:
    25 май 2009
    Сообщения:
    10
    Симпатии:
    0
    Вот код
    Код (Text):
    1.  
    2.  $file = fopen("data.txt","r");
    3.   while (!feof ($file)) {
    4.  $w = explode("=", fgets ($file, 512));
    5.   $gen[$w[0]]=$w[1];
    6.  }
    данные считываются из файла и заносятся в массив, данных всего 500МБ, но 30млн строк(так много памяти скорее всего пожирает организация структуры двумерного массива)
     
  6. [vs]

    [vs] Суперстар
    Команда форума Модератор

    С нами с:
    27 сен 2007
    Сообщения:
    10.559
    Симпатии:
    632
    А что мешает считывать и записывать по 100Мб?
     
  7. bimcom

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

    С нами с:
    25 май 2009
    Сообщения:
    10
    Симпатии:
    0
    Мешает то, что нужно все данные загнать в память, а потом с ними работать, не выгружать/конвертировать а именно работать, по аналогии как загружают в память индекс для поиска по БД, так и тут этот файл должен структурированно лежать в массиве, который полностью в памяти.
     
  8. Psih

    Psih Активный пользователь
    Команда форума Модератор

    С нами с:
    28 дек 2006
    Сообщения:
    2.678
    Симпатии:
    6
    Адрес:
    Рига, Латвия
    bimcom
    Вам не PHP нужен, а C/C++, Java или ещё что-нить с типизированными типами данных. PHP для такого никак не предназначен, и уж точно не для лопачиния такого кол-ва данных в памяти.
     
  9. bimcom

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

    С нами с:
    25 май 2009
    Сообщения:
    10
    Симпатии:
    0
    Psih
    Скорее всего вы правы, но знаю я покачто только PHP, на изучение других языков времени свободного нет.
    В принципе PHP меня полностью устраивает и все на нем работает, только с большим объемом данных чет косяк, темболее на таком значение 1514 МБ, понимаю было место глюка 4 ГБ или 2ГБ (то что винда больше не выделяет, но вроде ключ прописал чтоб выделяла до 3х ) или было какоенибудь ограничение у PHP (например процесс больше 1,5ГБ не потребляет).
    В объщем непонятно почему ругается на нехватку памяти - ведь её полно, и в логи никаких ошибок не пишет.
    Может народ протестите у себя - сколько данных залить в память сможите, забив масси случайными цифрами? и отпишите у кого ошибка на 1,5ГБ не вылетела + сообщите персию ПХП.
     
  10. [vs]

    [vs] Суперстар
    Команда форума Модератор

    С нами с:
    27 сен 2007
    Сообщения:
    10.559
    Симпатии:
    632
    bimcom
    У меня memory_limit вообще закоменнтирован, тоже на 1.5Гб вылетает. Полагаю, это связано с ОС.

    Неверю (c) ;-)
     
  11. это Kreker должен говорить, в его городе жил Станиславский ))
     
  12. bimcom

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

    С нами с:
    25 май 2009
    Сообщения:
    10
    Симпатии:
    0
    Представьте (в реальности данные похожи, но уровень энтропии выше)
    Есть список в файле
    ФАМИЛИЯ ИМЯ=количество человек
    есть источник данных который поставляет новые пары ФАМИЛИЯ ИМЯ
    теперь нужно в банке данных увеличить число человек имеющих такуюже ИМЯ ФАМИЛИЯ на +1, а если такой пары ФАМИЛИЯ ИМЯ нет то создать и присвоить элементу кол-во =1
    Код (Text):
    1.  
    2. $gen["ПЕТР СЕРГЕЕВИЧ"]=5256781;
    3. $gen["АРТЕМ ВИКТОРОВИЧ"]=58975;
    4. $gen["АРТЕМ ЕВДОКИМОВИЧ"]=975;
    5. ...
    Если не держать это все в памяти, то скорость поиска и дозаписи/увеличения на 1 происходит крайне медленно.
    Пробовал делить на 3 массива:
    1массив - первые слова
    2массив - вторые слова
    3массив - хэш_измассива1 хэш_измассива2=число
    но расход на 3й массив по памяти увеличивается (т.к. это уже 3х мерный массив) и выигрыша почти нет.
    PS.
    БД работает медленнее на порядок, такчто она рассматривается только в самом последнем и крайнем случае.
    PSS.
    Если есть мысли как можно оптимизировать то что я делаю буду рад услышать советы.
     
  13. [vs]

    [vs] Суперстар
    Команда форума Модератор

    С нами с:
    27 сен 2007
    Сообщения:
    10.559
    Симпатии:
    632
    OMG!!!
    Во-первых, самая медленная БД будет работать на порядок быстрее этого монстра.
    Во-вторых, для очень быстрой работы с данными есть (по крайней мере в MySQL) тип таблицы HEAP (MEMORY), memcached в конце концов!
    В-третих, во всех СУБД есть кэширование, в вашем случае даже InnoDB не будет тормозить.
     
  14. bimcom

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

    С нами с:
    25 май 2009
    Сообщения:
    10
    Симпатии:
    0
    Чувствую что те тормаза которые были у меня с MySQL БД связаны с дефолтными настройками MySQL-я.

    Подскажите какие параметры нужно выставить если под базу я готов выделить 2,5ГБ оперативы
    Код (Text):
    1.  
    2. key_buffer            = 16K
    3. max_allowed_packet    = 1M
    4. table_cache           = 4
    5. sort_buffer_size      = 64K
    6. read_buffer_size      = 256K
    7. read_rnd_buffer_size  = 256K
    8. net_buffer_length     = 2K
    9. thread_stack          = 64K
    А также подскажите какие параметры нужно выставить если я захочу присвоить тип базе HEAP, чтобы сравнить производительность.
    PS.
    При создание индекса на поле из 2х слов (ставлю как уникальные) индекс получается равный данным(по объему).
     
  15. [vs]

    [vs] Суперстар
    Команда форума Модератор

    С нами с:
    27 сен 2007
    Сообщения:
    10.559
    Симпатии:
    632
    Давайте по-порядку...
    Что такое в данном случае - "тормоза"?
    Сколько запросов было в секунду?
    При каких операциях?
    Какой тип таблицы?

    И желательно код, который работал с БД.
     
  16. bimcom

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

    С нами с:
    25 май 2009
    Сообщения:
    10
    Симпатии:
    0
    Тормаза - медленная работа.
    Запросов - 800-1000 в секунду (из них 30% селекты 40% апдейты 30% инсерты)
    Операции - все, а особенно что побудило перенести все вычисления в память, так это быстрая дефрагментация БД (фрагментировались как файл таблицы так и файл индексов, скорость фрагментирования 100 фрагментов/минута и при кол-ве фрагментов >1000 кол-во запросов в секунду падало до 100, после проведения дефрагментации все снова летало)
    код

    Код (Text):
    1. SELECT * FROM data WHERE 2gram ='"$Words"' LIMIT 0 , 1
    если ничего не нашол
    Код (Text):
    1. INSERT INTO `data` ( `id` , `2gram` , `dop`) VALUES ('', '"$Words"', '')
    а если нашол то
    Код (Text):
    1. UPDATE `data` SET `dop` = '".$Dop."' WHERE `id` =".$row2["id"]." LIMIT 1 ;
    Теперь похоже понял откуда фрагментированность росла - из-за маленького кэша.
    PS.
    сейчас же скорость работы с массивом пропорциональна 10 000-15 000 запросам в секунду к БД. (сравнение было на данных что помещаются в память, и в БД залит такойже объем)
     
  17. [vs]

    [vs] Суперстар
    Команда форума Модератор

    С нами с:
    27 сен 2007
    Сообщения:
    10.559
    Симпатии:
    632
    Кажется, я вас понял. PHP предназначен для работы с небольшими объемами информации, лучше всего php работает со строками. Если вы все же хотите использовать php, то рекомендую использовать memcached.
     
  18. Amian

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

    С нами с:
    15 мар 2007
    Сообщения:
    189
    Симпатии:
    0
    Польза от memcached для данной задачи будет минимальна, его функция - кэширование наиболее часто повторяющихся запросов для оптимизации READ-a.

    bimcom,
    Смотри в сторону Berkley DB, идеально подходит для твоего случая (oracle BDB, memcacheDB, ...).

    http://www.oracle.com/technology/produc ... b-perf.pdf
     
  19. bimcom

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

    С нами с:
    25 май 2009
    Сообщения:
    10
    Симпатии:
    0
    Спс.
    Почитаю
     
  20. [vs]

    [vs] Суперстар
    Команда форума Модератор

    С нами с:
    27 сен 2007
    Сообщения:
    10.559
    Симпатии:
    632
    300 селектов в секунду - это не часто повторяющиеся READ'ы?
    memcached без разницы что хранить и для каких целей, чтение и запись работают одинаково быстро. Кроме того, встроеные фунции инкремента и дикремента.
     
  21. Amian

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

    С нами с:
    15 мар 2007
    Сообщения:
    189
    Симпатии:
    0
    В случае с мемкешд надо смотреть не на количество ридов в секунду, а на количество повторов идентичных запросов. Хорошо если данных сейчас 2ГБ и можно загрузить все данные сразу в память, а если через месяц уже будет 100 ГБ ? Где тут польза , если все запросы произвольны ?

    Про пользу мемкешд для записи это была шутка ? :roll:
     
  22. [vs]

    [vs] Суперстар
    Команда форума Модератор

    С нами с:
    27 сен 2007
    Сообщения:
    10.559
    Симпатии:
    632
    Если bimcom собирался хранить все данные в памяти, то значит не планируется, что будет 100Гб. И вообще не 2Гб, а 500Мб.
    Я имел ввиду, запись в память через memcached.
     
  23. bimcom

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

    С нами с:
    25 май 2009
    Сообщения:
    10
    Симпатии:
    0
    Пока замутил следующим образом:
    увеличил key_buffer до 2,5ГБ и запросы инсерта сделал отложенными - в результате скорость работы в начале очень низкая, но через 10 минут все попадает в кэш и скорость взлетает до 15 000 запросов/сек (теперь узкое место поставщик данных:) )
    Всем спасиба.
    (разбираться более подробно буду в этой проблеме когда данных будет на порядок больше)
     
  24. TheShock

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

    С нами с:
    30 май 2009
    Сообщения:
    1.255
    Симпатии:
    0
    Адрес:
    Київ
    Это делается не так. Все - намного проще. Через часок расскажу
     
  25. TheShock

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

    С нами с:
    30 май 2009
    Сообщения:
    1.255
    Симпатии:
    0
    Адрес:
    Київ
    Хочу всем дать совет. Когда программируете - будьте предельно осторожны. Я вот себе программировал на пхп, запросы выполнял, не успел оглянутся, как у меня уже Кубунту вместо Дебиана...