С ++ в системах с низким объемом памяти.Стандартные библиотеки используют всю память! - PullRequest
1 голос
/ 06 апреля 2011

Мне нужно сбрить как можно больше памяти.Я использую стандарт C ++ с STL.Программа не делает много (пока) и все еще занимает 960Kb [согласно top]!Размер исполняемого файла составляет всего 64 КБ.

Код длиной 3000 строк, я не собираюсь публиковать, очевидно.Я считаю, что проблема не в моем коде, а в системных библиотеках.

Одна функция main () (включает весь мой код, но не использует ее) использует 732 КБ ОЗУ !
Простой код:

int main() {
sleep(1000); //do nothing
return 0;
}
//Uses 732kb of RAM

В моем коде нет глобальных переменных (кроме тех, что в библиотеках, которые скрыты от меня).

Я используюстандартные библиотеки: libstdc ++ (STL), GNU libc.Также один BSD-сокет и libev и нестандартный класс веревки STL.

Есть ли какой-нибудь профилировщик памяти, который я могу запустить?

Платформа : Linux 2.6.18-32, 32-разрядный процессор, общая оперативная память 16 МБ, без подкачки
Компилятор : GCC 4
Стандартная библиотека : Компилятор GCC libstdc ++
КомпиляторОпции : -Os (без символов отладки)

Я не , интенсивно использующий шаблоны: контейнеры и итераторы, вот и все.Однако я интенсивно использую веревочный класс SGI STL.

Средой тестирования является базовый сервер под управлением Linux с 128 МБ ОЗУ, Pentium III 667 МГц, CentOS 5.5, без эмуляции.

ОБНОВЛЕНИЕ : Мне интересно, являются ли сами библиотеки (размер кода) причиной проблемы.Разве разделяемые библиотеки не требуют загрузки в ОЗУ?

Ответы [ 4 ]

2 голосов
/ 06 апреля 2011

ОБНОВЛЕНИЕ: мне интересно, являются ли сами библиотеки (размер кода) причиной проблемы.Разве разделяемые библиотеки не требуют загрузки в оперативную память?

Bingo.В Mac OS X, по крайней мере, Top включает размер общих библиотек в использование физической памяти.Разумеется, в памяти хранится только одна копия каждой библиотеки.

Проверьте документацию на top для обходного пути или просто зафиксируйте ее и используйте malloc_info().Будьте осторожны, чтобы найти способ учета кода, стека и глобального использования.

2 голосов
/ 06 апреля 2011

Начинайте убирать функциональность, пока не уменьшится использование памяти.Сначала сделайте все возможное - если вы можете заменить main на sleep(1000);, и ваше использование памяти все еще велико, посмотрите на код и статические данные - все, что инициализируется в глобальной области видимости или статически внутри класса или функции, вместе с экземплярами шаблонаразличные типы и символы отладки.

ОБНОВЛЕНИЕ : Удален неправильный комментарий о распределителях STL.Это может относиться к другим версиям компилятора / STL (проверьте историю, если вы хотите ее увидеть), но не применимо к этому вопросу.

Имейте в виду, что malloc / operator new часто скупится на предоставлениеосвободить память обратно в ОС, что приведет к тому, что ваша программа в целом не сократит свое видимое использование с течением времени;эта память будет повторно использоваться во всей вашей программе при будущих распределениях, поэтому обычно это не является большой проблемой, за исключением того, что ваши значения «использования памяти» остаются на уровне или около их верхней отметки на неопределенное время.

1 голос
/ 08 апреля 2011

Получить компоновщик для создания файла карты ссылок;Вы можете использовать это, чтобы точно определить, сколько статически связанного кода и пространства статических данных требует ваш код.

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

Если у вас 16 МБ ОЗУ, действительно ли это важно?Вероятно, что это сравнительно большие, но постоянные накладные расходы, и что ваш общий объем памяти не будет расти линейно с добавлением строк кода.

0 голосов
/ 11 апреля 2011

Поскольку целью является linux, я думаю, вы могли бы кое-что узнать о деталях использования памяти, в частности о компонентах разделяемой библиотеки, посмотрев файлы карт и файлов smaps в / proc / {pid_number}

...