Сколько памяти занимает переменная?

alekciy

Новичок
Сколько памяти занимает переменная?

PHP : 5.2.4
Apache : 2.0.61
ОС : WinXP Pro&SP2 32bit

Сколько ОЗУ занимаеют переменные различных типов? Особенно интерисуют ассоциативные массивы.

Хотел выяснить это на примере строковой переменно:
PHP:
<?php
echo memory_get_usage()."<br>";
$a = (string)'0';
echo memory_get_usage()."<br>";
?>
Кодировка однобайтная. Если в $a от 1 до 7 символов, то получаю 104 байта, если 8 - 31, то 88 байт, 32 - 39 136 байт, больше 40 символов, то 88 байт.
В общем полная неразбериха.

Так сколько же реально уходит на переменных разных типов?
 

alekciy

Новичок
korchasa
Да, насчет xdebug-а я как то не подумал. Тем более он у меня и так есть.

Только проблема в том, что xdebug_memory_usage() выдает теже результаты.
 

tony2001

TeaM PHPClub
>на memory_get_usage ругаются.

=)))

>Только проблема в том, что xdebug_memory_usage() выдает теже результаты.

можно подумать, что он откуда-то из другого места их узнает или каким-то иным способом.
конечно, они те же самые!
а результаты разные потом, что это чуть сложнее, чем "просто создать переменную".
memory manager выделяет бОльшими кусками и не освобождает маленькие куски для ускорения процесса.

вообще, постановка задачи меня всегда удивляла.
во-первых, непонятно ЗАЧЕМ.
во-вторых, неясно что именно под этим подразумевается: если, скажем, переменная была создана как $a = $b, то $a - это на самом деле $b с refcount = 2.
две разные переменные делят одну и ту же память. кто из них занимает сколько?
я уже молчу про ссылки, массивы, объекты и т.п.
 

alekciy

Новичок
tony2001
>можно подумать, что он откуда-то из другого места их
>узнает или каким-то иным способом.
Были такие же подозрения.

Зачем? Все просто. Я собираюсь работать с IPC, для создания сегмента разделяемой памяти нужно указать размер нужного сегмента. Там есть конечно дефолтное значение. Но я не уверен, что мне его хватит. К примеру я захочу там хранить индексный массив в 100 элемтов, каждый элемент это строка максимального размера 1024 символа (к примеру). Простым умножением получаем в районе 100кбайт. А если строка в многобайткой кодировке? А если массив многомерный? А если он ассоциативный? Что на что нужно будет умножить? Сколько данных уходит на хранение ключей для ассоциативного массивного?
В общем сразу возникли эти вопросы, а сразу всплыла проблема как это оценить. Тут меня memory_usage и озадачил.

Единственно что из соображений возникло, это через php создать сегмент, записать в него данные и череш шелл посмотреть состояние IPC. Сейчас пойду опробую.

-~{}~ 14.02.08 19:57:

Мда... ipcs говорит только общий объем отведенный на сегмент. А это я и без неё знаю.
 

korchasa

LIMB infected
Автор оригинала: tony2001
можно подумать, что он откуда-то из другого места их узнает или каким-то иным способом.
конечно, они те же самые!
Тогда я вообще не понимаю, зачем ее вводить надо было :(
 

tony2001

TeaM PHPClub
>Я собираюсь работать с IPC, для создания сегмента разделяемой памяти
>нужно указать размер нужного сегмента.

что ты туда будешь класть?
явно ведь не некую виртуальную "переменную", а некие данные.
вот их и меряй тогда.

>К примеру я захочу там хранить индексный массив в 100 элемтов, каждый элемент
>это строка максимального размера 1024 символа (к примеру). Простым
>умножением получаем в районе 100кбайт. А если строка в многобайткой
>кодировке? А если массив многомерный? А если он ассоциативный? Что на что
>нужно будет умножить? Сколько данных уходит на хранение ключей для
>ассоциативного массивного?

Если это всё из PHP, то во-первых для этого есть http://php.net/shmop.
Во-вторых, сериализуй и strlen().

Если это из C, то ты знаешь что и где копируешь, к чему вообще вопросы?

>Тогда я вообще не понимаю, зачем ее вводить надо было

что вводить?
 

alekciy

Новичок
tony2001
Он о xdebug_memory_usage(). Зачем вводить его, если он все равно использует memory_usage()
 

FractalizeR

Новичок
Ответ на ваш вопрос можно найти тут, если дело касается массивов:
http://bugs.php.net/bug.php?id=41053&edit=3

Фактически, каждое значение в массиве занимает минимум 52 байта. Т.е. если у вас массив в миллион элементов, он будет есть более 50 мегабайт памяти.

Строки, похоже, наиболее экономный способ хранения последовательности байт в памяти в PHP, поскольку занимают имеено столько байт, сколько в них находится в действительности плюс несколько байт на размер строки.
 

alekciy

Новичок
tony2001
Из PHP.
А какая разница между Shared Memory в IPC и shmop? Как я понял в shmop можно только строки записать, а IPC можно сразу любой из типов. И как я понимаю системы это разные.
С сериализацией конечно вариант, только сериализация/десериализация лишние действия. Кроме того в IPC меня привлекают семофоры. Именно поэтому Shared Memory я заюзал из IPC, а не shmop. Хотя сначала схватился за shmop.

-~{}~ 14.02.08 21:49:

FractalizeR
О! Спасибо! Уже хоть какая то определенность. Линк полезный, сейчас дочитаю...
 

tony2001

TeaM PHPClub
>Из PHP.
>А какая разница между Shared Memory в IPC и shmop?
это одно и то же, но в shmop все уже сделано для вас, чтоб вы там сами себе не додумывали всякую чушь.

>Как я понял в shmop можно только строки записать, а IPC можно сразу любой из типов.
> И как я понимаю системы это разные.
нихрена вы не понимаете.
нет никаких магических средств, чтобы положить переменную в память напрямую.
тот же шмоп и все остальные функции ТОЖЕ сериализуют переменные перед и десериализуют после.

> Кроме того в IPC меня привлекают семофоры.
IPC = inter-process communication
семафоры и шаред мемори - входят в это понятие.
 

alekciy

Новичок
Автор оригинала: tony2001
это одно и то же, но в shmop все уже сделано для вас, чтоб вы там сами себе не додумывали всякую чушь.
Одно и тоже? Принцип то может и один, а реализация как я понимаю разная. Я же не могу из shmop получить доступ к разделяемой памяти из IPC.

Автор оригинала: tony2001
нихрена вы не понимаете.
нет никаких магических средств, чтобы положить переменную в память напрямую.
тот же шмоп и все остальные функции ТОЖЕ сериализуют переменные перед и десериализуют после.
Если бы это я понимал в полном объеме, то не спрашивал бы. Уточнять приходиться то, что в мане не освещено.
Если тоже сериализует, тогда зачем делать сериализацию по 2 раза, один раз в мое приложении, второй раз по дефолту. Или в случае передачи в shmop сериализованной строки вторая сериализация не проводиться?
 

tony2001

TeaM PHPClub
либо ты работаешь с шаред мемори напрямую и сериализацией занимаешься сам, либо делаешь это через некий враппер, которые делает это за тебя.

я, кстати, был не прав - это shm_put_var() делает сериализацию сама, а shmop_write() - это как раз прямой доступ к шаред мемори, но не суть важно.

>Я же не могу из shmop получить доступ к разделяемой памяти из IPC.

конечно можешь.
это одна и та же память.
 

alekciy

Новичок
tony2001
Почему же не важно? Как минимум в первом случае применять сериализацию в приложении бессмыслено.

Да, точно, могу. Ошибся немного в идетификаторах, поэтому и выходило, что пытался читать другой сегмент памяти. Сейчас поправил и точно видно, что при использовании IPC массив храниться сериализованной строкой.

Спасибо tony2001, FractalizeR с вашей помощью я окончательно определился, что юзать буду shmop + сериализация. Сначала именно так и хотел, но смутило то, что в IPC можно любые типы данных хранить. Подумалось, может они так в каком либо оптимизированном виде хранять, чего с сериализацией заморачиваться. Ан нет... оказывается и там хранить просто строками.
 

weregod

unserializer
Так все-таки нет решения померить, сколько переменная любого типа занимает в памяти?

У нас на проекте утекает память, моя задача выяснить, где конкретно, проект на многие тысячи строк, очень хочется посчитать, сколько занимают в памяти некоторые структуры...
 

alekciy

Новичок
weregod
Ну как лично я понял волшебной функции или хотя бы алгоритма (хотя приблизительную прикидку можешь сделать исходя из поста FractalizeR) "посчитать память отведенную переменным" нет.
 

Alexandre

PHPПенсионер
weregod хочу заметить, что утечка памяти и много занимает - это разные вещи.
проект на многие тысячи строк, очень хочется посчитать, сколько занимают в памяти некоторые структуры...
раздели проект на части так, чтоб подгружались классы только те, которые должны вызываться, а не все разом. Конечно, так памяти ни на что не хватит если проект на многие тысячи строк.
использовать сложные структуры вложенных массивов ни есть хорошо, особенно если только из всей этой информации нужно всего лишь 20%.
массив в РНР ни есть массив как в паскале или Си, это довольно таки сложная структура, требующая дополнительную память, кроме занимаемой данными.
очень хочется посчитать, сколько занимают в памяти некоторые структуры...
vld тебе поможет
 

weregod

unserializer
накидал ф-цию, которая рекурсивно обходит любую сущность и, используя некоторые эмпирические константы и здравый смысл, подсчитывает "entity memory usage".

прикольно, что php5 не может делать array_search($object, $arrayOfParsedObjects), когда в $object есть ссылка на объект из $arrayOfParsedObjects, в котором в свою очередь есть ссылка на $object. но это лирика.

оказалось, что в php жутко жрет сам исходный код.
незенденный код на win32 php5 отъедает в памяти в 6 раз больше объёма кода (комментарии откидываются).
под *ксом коэффициент чуть поменьше...

причем зенденный код под win32 php5 жрет больше открытого, под никсом наеборот.
 
Сверху