The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

форумы  помощь  поиск  регистрация  майллист  вход/выход  слежка  RSS
"Размер процесса. Используемая память. Потоки."
Вариант для распечатки  
Пред. тема | След. тема 
Форум Программирование под UNIX (C/C++)
Изначальное сообщение [ Отслеживать ]

"Размер процесса. Используемая память. Потоки."  +/
Сообщение от Fx (ok) on 14-Ноя-11, 05:48 
Здравствуйте,

Есть демон на си++ с потоками. По моим подсчетам, должен занимать в памяти ~10 мегабайт, а он по данным из top жирнеет до 300M.

все объекты из памяти, сериализуются на диск и там уже реально отражают картину, и занимают 16 мегабайт суммарно. почему при перезапуске, при считывании этих объектов с диска, программа сново жирнеет до 160М примерно?

Думаю, может это потоки, каждый дублирует общую память? Т.е. сколько всего памяти нужно умножается на количество потоков? (хотя тоже не похоже, потоков при старте всего 6) На что смотреть? Как искать причину?

Спасибо

пс. да, и раз уже о потоках написал, то не понимаю почему gdb показывает что потоков 7, а не 6... 4 + 1 + поток прородитель main = 6.... откуда 7мой?

Ответить | Правка | Cообщить модератору

Оглавление

Сообщения по теме [Сортировка по времени | RSS]


1. "Размер процесса. Используемая память. Потоки."  +/
Сообщение от ACCA (ok) on 14-Ноя-11, 07:12 
> Здравствуйте,
> Есть демон на си++ с потоками. По моим подсчетам, должен занимать в
> памяти ~10 мегабайт, а он по данным из top жирнеет до
> 300M.

libс, stdc++, да мало ли голодных детей с ложками? И потом, ты какую память считаешь?

Ответить | Правка | ^ к родителю #0 | Наверх | Cообщить модератору

3. "Размер процесса. Используемая память. Потоки."  +/
Сообщение от Fx (ok) on 14-Ноя-11, 12:27 
>> Здравствуйте,
>> Есть демон на си++ с потоками. По моим подсчетам, должен занимать в
>> памяти ~10 мегабайт, а он по данным из top жирнеет до
>> 300M.
> libс, stdc++, да мало ли голодных детей с ложками? И потом, ты
> какую память считаешь?

метафора хороша, понравилось.
по теме - память из "top" колонка RES / SIZE, по сути не важно какая - все равно много. например: 179М - в опреативке, 262М фактически. и это только после запуска.

вчера лег отдыхать, после того как написал. и мысль как раз о std::map не давала покоя. самые многочисленные объекты хранятся в map<int,Object*>, где int - уникальный ключ. возможно эти map выжирает очень много памяти. сейчас буду проверять через свойство capaticy() вроде или дебагером, который ниже Вова посоветовал.

map - этот прийдется заменять на hash_map какой-нибудь видимо? искал раньше, видел hash_map от гугл неплохой по описанию, но пока не изучал. решил, что для прототипа и std::map подходит. да и с int ключем вроде он достаточно быстрый должен быть.

оптимизировать потребление std::map памятим возможно?

спасибо

Ответить | Правка | ^ к родителю #1 | Наверх | Cообщить модератору

2. "Размер процесса. Используемая память. Потоки."  +/
Сообщение от Вова on 14-Ноя-11, 09:40 
Каждый поток резервирует место под свой стек, по умолчанию это 8 мб, поэтому даже два потока съедят 16 метров, что больше ожидаемых вами 10ти.  Далее, память (куча) общая у всех потоков, поэтому никакие объекты c++ не дублируются по количеству потоков. Ошибки работы с памятью отлично отслеживаются валгриндом, практически все - кроме блоков, потраченных под вышеупомянутые стеки, для их деаллокации необходимо обязательно использовать либо pthread_join() либо pthread_detach().
Ответить | Правка | ^ к родителю #0 | Наверх | Cообщить модератору

4. "Размер процесса. Используемая память. Потоки."  +/
Сообщение от Fx (ok) on 14-Ноя-11, 12:40 
> Каждый поток резервирует место под свой стек, по умолчанию это 8 мб,
> поэтому даже два потока съедят 16 метров, что больше ожидаемых вами
> 10ти.  Далее, память (куча) общая у всех потоков, поэтому никакие
> объекты c++ не дублируются по количеству потоков. Ошибки работы с памятью
> отлично отслеживаются валгриндом, практически все - кроме блоков, потраченных под вышеупомянутые
> стеки, для их деаллокации необходимо обязательно использовать либо pthread_join() либо
> pthread_detach().

спасибо за наводку на дебагер, сейчас почитаю и попробую разобраться в нем. выше описал дополнительные моменты, скорей всего проблема в std::map<int,Object*> (около 60000) объектов на один map

также использую std::map<std::string, Object*> но количество объектов не так многочисленно (сейчас 2, будет до 100) на данный момент можно принебречь.

по поводу умолчания на поток по 8 мб, если ли мозможнось выделять меньше памяти и оправдано ли это?

пс. 10M - это сумма по объектам, после сериализации на диск. в памяти они должны занимать еще меньше, т.к. на диске строки используются, а в памяти - указатели.

Ответить | Правка | ^ к родителю #2 | Наверх | Cообщить модератору

5. "Размер процесса. Используемая память. Потоки."  +/
Сообщение от Fx (ok) on 14-Ноя-11, 16:17 
валгринд еще не поставил (старя весия фрибсд у меня) качаю новый дистрибутив.

std::map - отпадают, убрал самые крупные для теста - использование памяти заметно не упало,
а вот когда убираю объекты, хранящиеся в этих map, то сразу прихожу к 18M на процесс.

sifeof (объект) = 92 байт (без учета в нем пар map<int,int> - обычно количество 1-2 пары, т.е. в памяти пусть 110 байт будет даже.
на диске после сериализации в среднем 78 байт на объект.

70000 объектов = около 7 мегабайт.
7 * 4 = 28 мегабайт на эти объекты.
но почему приложение жирнеет при них на более чем 100 мегабайт ( 120-230 мб)...


Ответить | Правка | ^ к родителю #4 | Наверх | Cообщить модератору

6. "Размер процесса. Используемая память. Потоки."  +/
Сообщение от Fx (ok) on 14-Ноя-11, 21:48 
методом научного тыка нашел:
проблема в мутексах. один инициализированый мутекс занимает на вскидку около 600 байт(read/write мутекс) и 200 байт если перейти на обычные мутексы. что дальше делать не знаю и почему так. это очень много.
Ответить | Правка | ^ к родителю #5 | Наверх | Cообщить модератору

7. "Размер процесса. Используемая память. Потоки."  +/
Сообщение от Вова on 15-Ноя-11, 14:17 
> методом научного тыка нашел:
> проблема в мутексах. один инициализированый мутекс занимает на вскидку около 600 байт(read/write
> мутекс) и 200 байт если перейти на обычные мутексы. что дальше
> делать не знаю и почему так. это очень много.

Повторю совет начать использовать valgrind чем раньше, тем лучше, размер стека задаётся при помощи pthread_attr_setstacksize(), а мутексы можно сделать размером с int. Точнее, не классические мутексы, а с небольшим бузи-вейтом  - volatile int + атомарные бьюлтины  gcc  (compare_exchange и подобные)  + sched_yield(). Складывается впечатление, что у вас слишком большое количество мутексов.

Ответить | Правка | ^ к родителю #6 | Наверх | Cообщить модератору

8. "Размер процесса. Используемая память. Потоки."  +/
Сообщение от Fx (ok) on 15-Ноя-11, 17:00 
> Повторю совет начать использовать valgrind чем раньше, тем лучше, размер стека задаётся
> при помощи pthread_attr_setstacksize(), а мутексы можно сделать размером с int. Точнее,
> не классические мутексы, а с небольшим бузи-вейтом  - volatile int
> + атомарные бьюлтины  gcc  (compare_exchange и подобные)  +
> sched_yield().

За совет с валгридом отдельное спасибо еще раз. Уже поставил новую ОС и валгрид, правда, если я правильно понул суть, то пока для своих целей использовать не получится: нужно переписать приложение, чтобы при завершении освобождало всю память (чтобы увидеть утечки)
Буду читать документацию.

> Складывается впечатление, что у вас слишком большое количество мутексов.

Два мутекса на объект-сессию для "человека". В принципе, можно до одного сократить, врятли один человек будет создавать одновременные запросы к демону.

По проблеме памяти и мутексов, ошибка, видимо в реализации мутексов под FreeBSD 6.1 или при компиляции gcc. потому что после перехода на FreeBSD 8.2 тот же код и база стартует занимая не 250 мегабайт, а 50мб (учитывая что часть этой памяти - это сами потоки). Хотя все равно мутекс не равен int*2(rw mutex), но уже приемлемо.

Да, к слову, может кому-то будет интересно, у меня по результатам получилось на FreeBSD 6.1, что мутексы не инициализированные занимают не много
    pthread_rwlock_t aMutex;
но как только инициализируешь каждый pthread_rwlock_init(&aMutex, NULL); - сразу память сжирается.

а константный инициализатор вообще не работает:
pthread_rwlock_t        rwlock1 = PTHREAD_RWLOCK_INITIALIZER;


Ответить | Правка | ^ к родителю #7 | Наверх | Cообщить модератору

Архив | Удалить

Рекомендовать для помещения в FAQ | Индекс форумов | Темы | Пред. тема | След. тема




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру