С ++ в системах с низким объемом памяти. Стандартные библиотеки используют всю память!
Мне нужно сбрить как можно больше памяти. Я использую стандарт 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 ответа
Начните убирать функциональность, пока не уменьшится использование памяти. Пойдите крайность сначала - если вы можете заменить main
с sleep(1000);
и ваше использование памяти все еще высоко, посмотрите на код и статические данные - все, что инициализируется в глобальной области видимости или статически внутри класса или функции, наряду с экземплярами шаблона различных типов и символами отладки.
ОБНОВЛЕНИЕ: Удален неправильный комментарий о распределителях STL. Это может относиться к другим версиям компилятора /STL (проверьте историю, если вы хотите ее увидеть), но не применимо к этому вопросу.
Быть в курсе, что malloc
/operator new
будет часто скупиться на возвращение ОС свободной памяти, что приведет к тому, что ваша программа в целом не сократит свое видимое использование с течением времени; эта память будет повторно использоваться во всей вашей программе при будущих распределениях, поэтому, как правило, это не является большой проблемой, за исключением того, что ваши значения "использования памяти" остаются на уровне или около их верхней отметки на неопределенный срок.
ОБНОВЛЕНИЕ: мне интересно, являются ли сами библиотеки (размер кода) причиной проблемы. Разве общие библиотеки не требуют загрузки в оперативную память?
Бинго. В Mac OS X, по крайней мере, Top включает размер общих библиотек в использование физической памяти. Разумеется, в памяти хранится только одна копия каждой библиотеки.
Проверьте документацию для top
для обходного пути, или просто забить его и использовать malloc_info()
, Будьте осторожны, чтобы найти способ учета кода, стека и глобального использования.
Получить компоновщик для создания файла карты ссылок; Вы можете использовать это, чтобы точно определить, сколько статически связанного кода и пространства статических данных требует ваш код.
Стек, куча и разделяемые библиотеки являются дополнительными к этому и выделяются во время выполнения.
Если у вас есть 16 Мб оперативной памяти, это действительно имеет значение? Вероятно, что это сравнительно большие, но постоянные накладные расходы, и что ваш общий объем памяти не будет расти линейно с добавлением строк кода.
Поскольку целью является linux, я думаю, вы могли бы кое-что узнать о деталях использования памяти, в частности о компонентах совместно используемой библиотеки, просмотрев файлы карт и файлов smaps в /proc/{pid_number}