Как определить размер стека программы в Linux?

Как определить текущий размер стека программы в Linux?

Говорят, что размер стека каждой программы в Linux будет 8 МБ, но когда вы используете cat /proc//mmap, он показывает другой размер.

Кроме того, как определить размер стека связанных потоков? Так как сказано, что потоки имеют свой собственный стек?

3 ответа

Решение

Если вам просто нужен текущий размер стека, вы можете объявить переменную в верхней части main(), взять ее адрес и сравнить ее с адресом переменной, объявленной там, где вы определяете "current". Разница должна быть приблизительно равна размеру стека.

Если вы хотите узнать, сколько памяти зарезервировано для стека, вы можете проверить /proc/[pid]/maps, где область помечена как [stack]. Например, мой процесс atd имеет:

7fff72a41000-7fff72a56000 rw-p 00000000 00:00 0                          [stack]
0175b000-0177c000 rw-p 00000000 00:00 0                                  [heap]

что дает вам идею.

Подходящий трюк, которым поделился со мной мой друг, когда я хотел узнать максимальный размер стека, который использовала моя программа, заключался в следующем. Я представлю это здесь в случае, если кто-то найдет это полезным:)

1) В функции, вызываемой в начале main(), используйте alloca() или очень длинный массив, чтобы набросать 0xDEADBEEF или какую-либо другую такую ​​маловероятную константу на той части стека, которую вы ожидаете использовать. Эта память будет "освобождена", когда маленькая функция вернется.

2) В конце main, снова используйте alloca(), чтобы захватить область памяти и "искать" в ней любую магическую константу, которую вы использовали, чтобы набросать (вы можете попытаться найти первый блок из 64 из них или что-то пропустить области памяти, которые могли быть выделены, но просто никогда не использовались), и где указатель попадает, указывает ваше максимальное использование стека.

Не идеально, но это было полезно для того, что я делал!

Как предложил Стивен, существует разница между размером стека, зарезервированного для вашего потока, и стеком, который в данный момент используется вашим потоком.

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

pthread_attr_t attr;
size_t stacksize;

pthread_attr_init(&attr);
pthread_attr_getstacksize(&attr, &stacksize); 

printf("%u\n", stacksize); 

Это напечатает размер стека по умолчанию, зарезервированный при создании одного потока. Для меня это 8 Мб.

Вы можете изменить это, используя pthread_attr_setstacksize() и передав структуру attr в качестве 2 аргументов функции pthread_create.

Изменить: Может быть, вы также должны знать о ленивых проблем распределения. Ваши 8 МБ виртуального пространства не будут использовать 8 МБ физического пространства памяти, если вы не будете читать или писать в этом месте.

Хотя есть несколько способов узнать об этом в Linux вручную в /proc/и т.д. Недавно я обнаружил, что stackusage очень удобен, он перехватывает создание потоков и довольно точно отображает фактическое использование. Также работает для однопоточных приложений.

Другие вопросы по тегам