- Размер процесса. Используемая память. Потоки., ACCA, 07:12 , 14-Ноя-11 (1)
> Здравствуйте, > Есть демон на си++ с потоками. По моим подсчетам, должен занимать в > памяти ~10 мегабайт, а он по данным из top жирнеет до > 300M.libс, stdc++, да мало ли голодных детей с ложками? И потом, ты какую память считаешь?
- Размер процесса. Используемая память. Потоки., Fx, 12:27 , 14-Ноя-11 (3)
>> Здравствуйте, >> Есть демон на си++ с потоками. По моим подсчетам, должен занимать в >> памяти ~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 памятим возможно? спасибо
- Размер процесса. Используемая память. Потоки., Вова, 09:40 , 14-Ноя-11 (2)
Каждый поток резервирует место под свой стек, по умолчанию это 8 мб, поэтому даже два потока съедят 16 метров, что больше ожидаемых вами 10ти. Далее, память (куча) общая у всех потоков, поэтому никакие объекты c++ не дублируются по количеству потоков. Ошибки работы с памятью отлично отслеживаются валгриндом, практически все - кроме блоков, потраченных под вышеупомянутые стеки, для их деаллокации необходимо обязательно использовать либо pthread_join() либо pthread_detach().
- Размер процесса. Используемая память. Потоки., Fx, 12:40 , 14-Ноя-11 (4)
> Каждый поток резервирует место под свой стек, по умолчанию это 8 мб, > поэтому даже два потока съедят 16 метров, что больше ожидаемых вами > 10ти. Далее, память (куча) общая у всех потоков, поэтому никакие > объекты c++ не дублируются по количеству потоков. Ошибки работы с памятью > отлично отслеживаются валгриндом, практически все - кроме блоков, потраченных под вышеупомянутые > стеки, для их деаллокации необходимо обязательно использовать либо pthread_join() либо > pthread_detach().спасибо за наводку на дебагер, сейчас почитаю и попробую разобраться в нем. выше описал дополнительные моменты, скорей всего проблема в std::map<int,Object*> (около 60000) объектов на один map также использую std::map<std::string, Object*> но количество объектов не так многочисленно (сейчас 2, будет до 100) на данный момент можно принебречь. по поводу умолчания на поток по 8 мб, если ли мозможнось выделять меньше памяти и оправдано ли это? пс. 10M - это сумма по объектам, после сериализации на диск. в памяти они должны занимать еще меньше, т.к. на диске строки используются, а в памяти - указатели.
- Размер процесса. Используемая память. Потоки., Fx, 16:17 , 14-Ноя-11 (5)
валгринд еще не поставил (старя весия фрибсд у меня) качаю новый дистрибутив.std::map - отпадают, убрал самые крупные для теста - использование памяти заметно не упало, а вот когда убираю объекты, хранящиеся в этих map, то сразу прихожу к 18M на процесс. sifeof (объект) = 92 байт (без учета в нем пар map<int,int> - обычно количество 1-2 пары, т.е. в памяти пусть 110 байт будет даже. на диске после сериализации в среднем 78 байт на объект. 70000 объектов = около 7 мегабайт. 7 * 4 = 28 мегабайт на эти объекты. но почему приложение жирнеет при них на более чем 100 мегабайт ( 120-230 мб)...
- Размер процесса. Используемая память. Потоки., Fx, 21:48 , 14-Ноя-11 (6)
методом научного тыка нашел: проблема в мутексах. один инициализированый мутекс занимает на вскидку около 600 байт(read/write мутекс) и 200 байт если перейти на обычные мутексы. что дальше делать не знаю и почему так. это очень много.
- Размер процесса. Используемая память. Потоки., Вова, 14:17 , 15-Ноя-11 (7)
> методом научного тыка нашел: > проблема в мутексах. один инициализированый мутекс занимает на вскидку около 600 байт(read/write > мутекс) и 200 байт если перейти на обычные мутексы. что дальше > делать не знаю и почему так. это очень много.Повторю совет начать использовать valgrind чем раньше, тем лучше, размер стека задаётся при помощи pthread_attr_setstacksize(), а мутексы можно сделать размером с int. Точнее, не классические мутексы, а с небольшим бузи-вейтом - volatile int + атомарные бьюлтины gcc (compare_exchange и подобные) + sched_yield(). Складывается впечатление, что у вас слишком большое количество мутексов.
- Размер процесса. Используемая память. Потоки., Fx, 17:00 , 15-Ноя-11 (8)
> Повторю совет начать использовать 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;
|