domxml жрет память?

varan

Б̈́̈̽ͮͣ̈Л̩̲̮̻̤̹͓ДͦЖ̯̙̭̥̑͆А͇̠̱͓͇̾ͨД͙͈̰̳͈͛ͅ
domxml жрет память?

Я написал скрипт, который обрабатывает файл в несколько десятков мегабайт, который состоит из маленьких иксэмелек. Я их обрабатываю с помощью domxml
Так вот, на полпути скрипт начинает дико тормозит, и винда пишет, что ей мало памяти. Кто-нибудь сталкивался с этим?
 

[DAN]

Старожил PHPClub
Вполне логично.
Ты знаком с моделью DOM ?
Представь, помимо того, что скрипт должен разместить в памяти десятки Мб, php еще должен построить и объектную модель этих данных. А это еще дополнительный расход памяти.
К тому же для каждого чаилда выделяется фиксированный объем памяти (8 Мб по-умолчанию). Естесственно, памяти хватать не будет.

Вылечить можно так:
1) Обрабатывать "маленькие иксэмэльки"
2) Использовать SAX-парсер (php работает с expat).

Приемущества второго пункта в том, что работа с xml-данными с помощью expat встроена в php по-умолчанию.
 

Entropy

Guest
Не понял! Какие 8 Мб под киндера??? Откуда такие сведения?
 

varan

Б̈́̈̽ͮͣ̈Л̩̲̮̻̤̹͓ДͦЖ̯̙̭̥̑͆А͇̠̱͓͇̾ͨД͙͈̰̳͈͛ͅ
Автор оригинала: [DAN]
Вылечить можно так:
1) Обрабатывать "маленькие иксэмэльки"
2) Использовать SAX-парсер (php работает с expat).

Приемущества второго пункта в том, что работа с xml-данными с помощью expat встроена в php по-умолчанию.
Domxml в моем случае в 100 раз удобнее.
Я, кстати, пробовал делать каждый раз unset($root), но это не помогло. Есть ли какие-нибудь другие способы убивать эти чертовы домы?
 

Андрей М.

Guest
[DAN], по-моему 8 мегабайт на ребенка - это действительно слишком:) У меня наверное ни один скрипт тогда бы не работал.

varan, если у тебя все равно винды, попробуй использовать не domxml, а msxml, он, имхо, побыстрее и лучше.

А вообще xml-файл в несколько 10 мегабайт - это сильно.
 

[DAN]

Старожил PHPClub
1)
;;;;;;;;;;;;;;;;;;;
; Resource Limits ;
;;;;;;;;;;;;;;;;;;;

memory_limit = 8M ; Maximum amount of memory a script may consume (8MB)

2) Десятки Мегабайт данных - это действительно ОЧЕНЬ много.
Если можно, бей файл на части и уже их обрабатывай.
Если нельзя, придется все-таки смотреть в сторону SAX или, как посоветовал Андрей М., в сторону MSXML. Хотя, полагаю, для MSXML такой объем данных тоже не подарок.

Вобщем, уменьшай объем данных, либо наращивай мощность сервера.
 

[DAN]

Старожил PHPClub
Автор оригинала: varan Есть ли какие-нибудь другие способы убивать эти чертовы домы?
Следи за ссылками и копиями.
unset для всего документа должен помогать. Но, насколько я помню, память как таковая не освобождается, а просто убиваются все указатели. Впоследующей работе скрипта эта память может быть использована, как свободная.
 

varan

Б̈́̈̽ͮͣ̈Л̩̲̮̻̤̹͓ДͦЖ̯̙̭̥̑͆А͇̠̱͓͇̾ͨД͙͈̰̳͈͛ͅ
Автор оригинала: Андрей М.
[DAN], по-моему 8 мегабайт на ребенка - это действительно
Да это ставится в php.ini. Я пробовал делать 100Мб. Один хрен.
varan, если у тебя все равно винды, попробуй использовать не domxml, а msxml, он, имхо, побыстрее и лучше.
А это что за зверь?
 

[DAN]

Старожил PHPClub
Это парсер от мелкомягких. Очень продвинутая софтина.
Поддерживает практически всю спеку по xml & xslt. Плюс, как всегда, свои фичи имеет.

Сходи, почитай тут http://go.microsoft.com/fwlink/?LinkId=3999

И, еще раз, настоятельно рекомендую уменьшить объем данных. Десятки Мб - это слишком много !
 

varan

Б̈́̈̽ͮͣ̈Л̩̲̮̻̤̹͓ДͦЖ̯̙̭̥̑͆А͇̠̱͓͇̾ͨД͙͈̰̳͈͛ͅ
И, еще раз, настоятельно рекомендую уменьшить объем данных. Десятки Мб - это слишком много !
Может, я неправильно объяснил?
Я ведь просто грубо говоря, 100000 раз анализирую маленькую иксэмэльку. По идее, не должно иметь никакого значения, сколько их штук, 5 или 5 млн. Просто видимо domxml резервирует память для каких-то объектов и не уничтожает их при unset($root).
 

Said

Guest
Память считается свободной когда на нее нет ссылок (насколько я понимаю работу GC PHP)
unset($root) уничтожает ссылку на корень дерева, но дочерние эл-ты имеют ссылку на родителя. Поэтому память не освобождается. Над юзать специальные методы класса предназначенные для уничтожения объекта
 

Flying

Guest
Для DOM XML объектов это не так, т.к. они не являются объектам PHP, а всего лишь обертками для данных libxml2. Поскольку объекты libxml2 уничтожаются при завершении работы скрипта - каждый созданный объект хранится в памяти все это время. Отсюда и сжирание памяти.
Вариантов решения два:
1. Можно сделать цикл, например обработал 10 раз, вышел из цикла в сделал header('Location: ') на самого себя. Извращенно, но работать будет.
2. В 4.3.2 появился метод уничтожения объекта DOM XML. Как назвается - не помню, смотри в ChangeLog. Возможно это тебе поможет.
 

Qasimodo

Новичок
Автор оригинала: Said
Память считается свободной когда на нее нет ссылок (насколько я понимаю работу GC PHP)
unset($root) уничтожает ссылку на корень дерева, но дочерние эл-ты имеют ссылку на родителя. Поэтому память не освобождается. Над юзать специальные методы класса предназначенные для уничтожения объекта
$document->unlink_node($root),
или (предрочтительно) $document->free();
 

[DAN]

Старожил PHPClub
1) unlink_node
Deletes the node from tree, but not from memory
2) free
Frees xmldoc and removed objects from hash
Тут может и освобождает.
 

slach

Новичок
хммм =)) странно... последняя ДАТА сообщения... Алесандр что это с вами ?
 

su1d

Старожил PHPClubа
хехе, похоже admin занялся XML'ем и сделал поиск =)
 
Сверху