LINUX.ORG.RU

как ограничить потребление виртуальной памяти в приложении


0

0

Есть проект (консольный чат) на Си/С++. Использование оперативной памяти - примерно 1,4 Мб. При этом использование виртуальной памяти доходит до 70 Мб! Используется динамическая загрузка библиотек (парочка небольших модулей). Думал уже какие-то большие утечки памяти - проверил ccmalloc-ом - общая выделенная память порядка 400 Кб, ну и утечек нашёл на 60 Кб. Это я всё пофиксю, но вот как бороться с 70Мб виртуальной памяти? На моём ноутбуке проект не запускается (ноут с 32 ОЗУ - malloc вываливается с ошибкой).

Вопрос - как можно разобраться в этом?

Я извиняюсь, а куда же девать загруженные glibc, libdl, динамический загрузчик? они же тоже сидят в виртуальном пространстве процесса и памяти откушиваают немало.

jek_
()
Ответ на: комментарий от jek_

Проверил - при создании каждого потока выделяется 8192К виртуальной памяти. В результате при создании 6-ти потоков выделяется почти 50Мб виртуальной памяти... Причём проверил на обычном тестовом приложении.

Пример pmap тестового приложения:
27724: ./main
08048000 4K r-x-- /data/work/Linux/work_c/temp/pthreads/main
08049000 4K rw--- /data/work/Linux/work_c/temp/pthreads/main
0804a000 132K rw--- [ anon ]
b7552000 4K ----- [ anon ]
b7553000 8196K rw--- [ anon ]
b7d54000 1092K r-x-- /lib/libc-2.3.5.so
b7e65000 4K r---- /lib/libc-2.3.5.so
b7e66000 12K rw--- /lib/libc-2.3.5.so
b7e69000 8K rw--- [ anon ]
b7e6b000 32K r-x-- /usr/lib/gcc/i686-pc-linux-gnu/3.4.4/libgcc_s.so.1
b7e73000 4K rw--- /usr/lib/gcc/i686-pc-linux-gnu/3.4.4/libgcc_s.so.1
b7e74000 132K r-x-- /lib/libm-2.3.5.so
b7e95000 8K rw--- /lib/libm-2.3.5.so
b7e97000 784K r-x-- /usr/lib/gcc/i686-pc-linux-gnu/3.4.4/libstdc++.so.6.0.3
b7f5b000 20K rw--- /usr/lib/gcc/i686-pc-linux-gnu/3.4.4/libstdc++.so.6.0.3
b7f60000 24K rw--- [ anon ]
b7f66000 56K r-x-- /lib/libpthread-2.3.5.so
b7f74000 4K r---- /lib/libpthread-2.3.5.so
b7f75000 4K rw--- /lib/libpthread-2.3.5.so
b7f76000 8K rw--- [ anon ]
b7f82000 4K rw--- [ anon ]
b7f83000 84K r-x-- /lib/ld-2.3.5.so
b7f98000 4K r---- /lib/ld-2.3.5.so
b7f99000 4K rw--- /lib/ld-2.3.5.so
bf883000 84K rw--- [ stack ]
ffffe000 4K ----- [ anon ]
total 10716K

Приложение просто создаёт поток, в котором стоит sleep(). В результате простого создания потока приложение потребляет 10М вирт. памяти.

progserega
() автор топика

пожалую стоит компилять с опциями -O3 -g0

чтобы отрезать от elf`а всё ненужное man strip

PS. судя по вашему сообщению на opennet.ru вы используете mpi для передачи текстов и соответсенно тянете libm..проверьте, возможно вы слинковались с отладочными версиями библиотек.

MKuznetsov ★★★★★
()
Ответ на: комментарий от jek_

Во время исследования исходного проекта выяснилось следующее:

1) Запускаю приложение - вирт. памяти >3Мб

2) Приложение загружает модули расширений - вирт. памяти ~3,5 Мб

3) Стартуют потоки в приложении - вирт памяти ~30Мб

4) Стартуют потоки в модулях - вирт. памяти 70Мб

Могу привести вывод pmap. Но там то же самое почти, только лишь за исключением того, что не одна, а шеть областей выделено по 8192К. (т.к. столько потоков).

progserega
() автор топика
Ответ на: комментарий от MKuznetsov

скомпилял все модули и главный бинарник с -O3 -g0, сделал strip -s все_бинарники

Результат:

30167: ./govorilka
08048000 80K r-x-- /data/work/Linux/work_c/network/govorilka/client/govorilka
0805c000 4K rw--- /data/work/Linux/work_c/network/govorilka/client/govorilka
0805d000 132K rw--- [ anon ]
b4c85000 4K ----- [ anon ]
b4c86000 8192K rw--- [ anon ]
b5486000 4K ----- [ anon ]
b5487000 8192K rw--- [ anon ]
b5c87000 4K ----- [ anon ]
b5c88000 8192K rw--- [ anon ]
b6488000 4K ----- [ anon ]
b6489000 8192K rw--- [ anon ]
b6c89000 4K ----- [ anon ]
b6c8a000 8192K rw--- [ anon ]
b748a000 4K ----- [ anon ]
b748b000 8192K rw--- [ anon ]
b7c8b000 20K r-x-- /lib/libgpm.so.1.19.0
b7c90000 4K rw--- /lib/libgpm.so.1.19.0
b7c91000 224K r-x-- /lib/libncurses.so.5.4
b7cc9000 32K rw--- /lib/libncurses.so.5.4
b7cd1000 4K rw--- [ anon ]
b7cd2000 48K r-x-- /data/work/Linux/work_c/network/govorilka/client/modules/mpi_ncurses/mpi_ncurses .so
b7cde000 4K rw--- /data/work/Linux/work_c/network/govorilka/client/modules/mpi_ncurses/mpi_ncurses .so
b7cdf000 8K rw--- [ anon ]
b7ce1000 1092K r-x-- /lib/libc-2.3.5.so
b7df2000 4K r---- /lib/libc-2.3.5.so
b7df3000 12K rw--- /lib/libc-2.3.5.so
b7df6000 8K rw--- [ anon ]
b7df8000 32K r-x-- /usr/lib/gcc/i686-pc-linux-gnu/3.4.4/libgcc_s.so.1
b7e00000 4K rw--- /usr/lib/gcc/i686-pc-linux-gnu/3.4.4/libgcc_s.so.1
b7e01000 132K r-x-- /lib/libm-2.3.5.so
b7e22000 8K rw--- /lib/libm-2.3.5.so
b7e24000 784K r-x-- /usr/lib/gcc/i686-pc-linux-gnu/3.4.4/libstdc++.so.6.0.3
b7ee8000 20K rw--- /usr/lib/gcc/i686-pc-linux-gnu/3.4.4/libstdc++.so.6.0.3
b7eed000 20K rw--- [ anon ]
b7ef2000 8K r-x-- /lib/libdl-2.3.5.so
b7ef4000 8K rw--- /lib/libdl-2.3.5.so
b7ef6000 4K rw--- [ anon ]
b7ef7000 56K r-x-- /lib/libpthread-2.3.5.so
b7f05000 4K r---- /lib/libpthread-2.3.5.so
b7f06000 4K rw--- /lib/libpthread-2.3.5.so
b7f07000 8K rw--- [ anon ]
b7f0b000 32K r-x-- /data/work/Linux/work_c/network/govorilka/client/modules/mproto_tcp/mproto_tcp.s o
b7f13000 4K rw--- /data/work/Linux/work_c/network/govorilka/client/modules/mproto_tcp/mproto_tcp.s o
b7f14000 84K r-x-- /lib/ld-2.3.5.so
b7f29000 4K r---- /lib/ld-2.3.5.so
b7f2a000 4K rw--- /lib/ld-2.3.5.so
bf813000 88K rw--- [ stack ]
ffffe000 4K ----- [ anon ]
total 52164K

mpi_ncurses.so - это мой модуль пользовательского интерфейса.

Всю погоду делают 6 потоков по 8Мб каждый... Почем у потоки едят столько - в этом сложность...

progserega
() автор топика
Ответ на: комментарий от progserega

> Всю погоду делают 6 потоков по 8Мб каждый... Почем у потоки едят столько - в этом сложность...

Потому что у них такой размер стека. Что же в этом сложного?

anonymous
()
Ответ на: комментарий от anonymous

И то верно, только у меня в генте стек 8Мб, а на соседней слаквари и дебиане по 2 Мб.

Вообще - всем спасибо за помощь!

Разобрался. Пересобрал всё с оптимизацией, пострипал и на ноутбуке пошло всё без проблем.

progserega
() автор топика
Ответ на: комментарий от progserega

Да, по умолчанию у тредов стеки здоровенные, но их всегда можно сделать такими, какие нужно. man pthread_create.

jek_
()
Ответ на: комментарий от progserega

А вот интересно ... есть ли какая-нибудь разница между стрипнутым и нестрипнутым бинарником с точки зрения расхода памяти? По идее, символы живут в отдельной секции, которая в память не читается, но нет ли еще каких-нибудь обстоятельств, влияющих на ситуацию?

anonymous
()
Ответ на: комментарий от anonymous

>есть ли какая-нибудь разница между стрипнутым и нестрипнутым бинарником с точки зрения расхода памяти?

никакой

только место на диске

cvv ★★★★★
()
Ответ на: комментарий от cvv

>никакой

Насколько это достоверно? Хотелось бы ссылочку на какой-нибудь умный текст.

Есть C++, есть разные режимы линковки и т.д. Про rtti я не говорю, это вещь отдельная, конечно.

anonymous
()
Ответ на: комментарий от anonymous

Этот вопрос в этом форуме пару раз обсуждался, воспользуйтесь поиском.

можете поковырять сырцы ядра в районе розпарсивания elf-бинарника

cvv ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.