LINUX.ORG.RU

php. Использование памяти.


0

1

У меня на операционном столе объект wrap (в рамках процедуры рефакторинга)

wrap = 337.4 KБ
=================
structure = 15.57 КБ
before = 21.21 КБ
after = 42.67 КБ
id = 0 КБ
class_name = 0 КБ
display = 0.01 КБ
tmpl_folder = 0.04 КБ
users_tmpl_folder = 0.04 КБ
theme = 0.01 КБ
title = 0 КБ
comment = 0 КБ
name = 0 КБ
description = 0 КБ
width = 0 КБ
height = 0 КБ
active = 0 КБ
visible = 0 КБ
================
Всего = 79.55 KБ

Где

  • wrap = 337.5 KБ - объём занимаемой памяти объекта(замерялся методом съёма memory_get_usage до и после создания)
  • structure = 15.57 КБ и нижеследующие - длинна «сериализованного»(через print_r) параметра structure этого объекта
  • Всего = 79.55 KБ - общий объём сериализованных атрибутов объекта

Вопрос: куда делись 250 КБ? Неужели в PHP для служебных структур используется СТОЛЬКО памяти? Или там память из под временных переменных по выходу из функций не освобождается?

Кстати, вот пример других таких обжектов

banners = 20.1 KБ
=====================
banners = 5.18 КБ
structure = 1.59 КБ
before = 0.01 КБ
after = 0.01 КБ
id = 0.01 КБ
class_name = 0.01 КБ
display = 0.01 КБ
tmpl_folder = 0.05 КБ
users_tmpl_folder = 0.04 КБ
theme = 0.01 КБ
title = 0 КБ
comment = 0 КБ
name = 0 КБ
description = 0 КБ
width = 0 КБ
height = 0 КБ
active = 0 КБ
visible = 0 КБ
=====================
Всего = 6.92 KБ
logo = 2.9 KБ
======================
src = 0 КБ
title = 0.01 КБ
alt = 0.01 КБ
url = 0 КБ
width = 0 КБ
height = 0 КБ
structure = 0.13 КБ
before = 0.01 КБ
after = 0.01 КБ
id = 0.01 КБ
class_name = 0 КБ
display = 0.01 КБ
tmpl_folder = 0.04 КБ
users_tmpl_folder = 0.04 КБ
theme = 0.01 КБ
comment = 0 КБ
name = 0 КБ
description = 0 КБ
active = 0 КБ
visible = 0 КБ
=======================
Всего = 0.29 KБ

То есть соотношение «стибренного» примерно сохраняется.

Как вы уже догадались, все они потомки обхего родителя.

★☆☆

>Или там память из под временных переменных по выходу из функций не освобождается
Именно.
GC вроде пилят, но когда заработает - хз.

iSage ★★★★
()
Ответ на: комментарий от iSage

>GC вроде пилят, но когда заработает

Ну, вот, у меня Jabber-бот на PHP неделями висит. И утечек памяти не наблюдаю :)

KRoN73 ★★★★★
()
Ответ на: комментарий от KRoN73

Дело не в течке. Память помечается «к освобождению» и через какое-то время действительно освободится (неизвестно когда, правда.).
Но получить обратно память прямо здесь и сейчас никак. И никакие unset'ы не помогут.

iSage ★★★★
()
Ответ на: комментарий от iSage

Если я правильно понял - вы описали беду GC из виртуальной машины Java. Как минимум там точно так же можно пометить к освобождению - но реальное освобождение произойдет когда GC будет угодно. Или вы имели в виду что то другое?

TheKnight ★★★
()
Ответ на: комментарий от TheKnight

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

iSage ★★★★
()
Ответ на: комментарий от iSage

>И никакие unset'ы не помогут.

Кстати, меня именно спасают :) При работе с скрипте со многими сотнями тысяч больших объектов, я раз в N циклов вызываю unset на массивы кешей — и память тут же освобождается :)

KRoN73 ★★★★★
()
Ответ на: комментарий от TheKnight

>но реальное освобождение произойдет когда GC будет угодно

Или когда будет вызван System.gc();

Иногда выгодно вызывать его периодически в минуты простоя вручную, чем ждать, пока у системы кончится память и он будет вызван в неподходящий момент под высокой нагрузкой :)

KRoN73 ★★★★★
()
Ответ на: комментарий от iSage

>Расставляем в конце цикла unset, ожидая, что это освободить уже ненуужные данные, и... получаем всю ту же нехватку памяти

Именно так и делаю. И… память освобождается! :) При чём, ладно бы, 5.3 с переписанным сборщиком мусора, но и в 5.2 и раньше также было.

KRoN73 ★★★★★
()
Ответ на: комментарий от iSage

>Освобождается, но далеко не все. Особенно все тухло с дочерними объектами.

Ну, даже не знаю :) У меня основной пожиратель памяти — кеш-хэши, вида $cache['object_uid'] => $object

Собственно, в рамках одного процесса однажды инициированный объект всегда прописывается в кэш, чтобы потом, при повторных запросах на его загрузку, сразу брать его из кэша.

Естественно, что каждый объект ссылается ещё и на другие объекты (которые тоже кешируются).

Делаешь цикл по паре сотен тысяч новостей (а каждая новость — это ещё объекты пользователей, источников, сюжетов, архивов, предприятий, персон и т.п.) — память уходит сотнями мегов. Делаешь сброс кеша, скажем, через каждую тысячу новостей — пиковая потребность в памяти уже ограничивается десятками мегабайт и при каждом сбросе падает почти до начального значения. Реально, конечно, не совсем до начального, у меня есть и другие, более мелкие кеши, которые чистить так часто смысла нет, но факт, что основная часть памяти — освобождается :)

KRoN73 ★★★★★
()
Ответ на: комментарий от KRoN73

То есть в PHP все таки управление вызовом GC есть? Это очень даже интересно..

Я имел в виду именно пхп.

Прошу прощения, выразился неаккуратно. В Java похожая проблема.

TheKnight ★★★
()
Ответ на: комментарий от TheKnight

>То есть в PHP все таки управление вызовом GC есть?

Прямого вызова нет (по крайней мере я такого не знаю), но unset у меня память освобождает :) Если освобождаемые объекты кто-то ещё не держит, естественно, а то может быть как в Java — в системе где-то есть забытая ссылка на объект, ты делаешь освобождение «основной» ссылки на него, а он не освобождается.

Ну и до 5.3, вроде, были проблемы с кольцевыми ссылками ($post содержит в себе ссылку на $user, который ссылается на упомянутый в начале $post — если освободить на них внешние ссылки, они всё равно не будут удалены). Но у меня на задачах с большим количеством объектов такой проблемы не было. В смысле — без кольцевых ссылок был. А там, где были кольцевые ссылки, там задачи одноразовые и нересурсоёмкие.

KRoN73 ★★★★★
()
Ответ на: комментарий от KRoN73

Понятно, ситуация чисто Java'образная. Там System.gc тоже есть. Как и unset. НО помогает слабо - GC работает тогда. когда хочет. Хотя правильное использование ссылок помогает когда надо экономить память...

TheKnight ★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.