|
4 / 4 / 2
Регистрация: 13.11.2014
Сообщений: 108
|
||||||||||||||||
Освобождение памяти после статических переменных27.09.2023, 11:17. Показов 3100. Ответов 55
Всем доброго времени суток)
Знааю знаю, избитая тема, но всё-таки хотелось бы прочесть что-то конкретное по этому поводу и вообще получше понять как это работает. В общем и целом имеем на борту под виртуалкой "Centos 7" с "GCC 4.8.5" (поддерживается максимум C++14 стандарт) компилятором и пытаемся сделать так, чтобы у нас после выполнения функции произошло высвобождение памяти, которая ей выделилась. Потому-что перед стартом функции мы имеем в ОП 168 Кб, а после уже все 30 Мб. Хотелось бы как-то устранить это досадное недоразумение, ведь если и дальше так выстраивать работу программы, то после пары десятков вызовов различных ёмких функций у неё же никаких ресурсов ОП не хватит( Собстно вот код для примера в main.cpp: Кликните здесь для просмотра всего текста
Компилим всё это дело в командной строке:
А то что мы там увидим прикреплено в картинках в приложении. Была естественно догадка, что это всё освободится, если чем-то забить память другим, НО чуда увы не произошло( Там вообще после 4Гб всё в своп полезло и стало хорошо подтормаживать, а 30Мб как были, так и остались на месте. Да я конечно знаю про указатели и delete, НО мне интересно, а как в этом случае освобождать память? //которая ещё и по идее сама должна была освободиться после выполнения функции, но чуда не произошло, да и вообще не предвидится на горизонте( _ Да и вообще с чем связано такое поведение? Это особенности C++14 или так моя версия GCC с ним работает или это ещё всё и вкупе на не самой новой CentOS7? Откуда вообще у такого поведения ноги растут и как с этим бороться?
0
|
||||||||||||||||
| 27.09.2023, 11:17 | |
|
Ответы с готовыми решениями:
55
Выделение и освобождение памяти для локальных переменных функций
Освобождение памяти после std:bind |
|
267 / 199 / 30
Регистрация: 26.11.2022
Сообщений: 862
|
|
| 27.09.2023, 12:44 | |
|
то что вы освободили память в программе это не значит что вектор (или malloc что у него под капотом) передал эту память системе. аллокаторы памяти немного по другому работают.
этим конечно можно управлять - но не с использованием STL.
0
|
|
|
4 / 4 / 2
Регистрация: 13.11.2014
Сообщений: 108
|
|
| 27.09.2023, 12:55 [ТС] | |
|
хмм, ok, а как ими с помощью чего-то другого управлять?
0
|
|
|
267 / 199 / 30
Регистрация: 26.11.2022
Сообщений: 862
|
|||||||||||
| 27.09.2023, 13:06 | |||||||||||
|
для начала пример: простая программа
Кликните здесь для просмотра всего текста
и её вывод : Кликните здесь для просмотра всего текста
У вас используется STL - да ещё вы постоянно меняете размер - в строке 18 постоянно меняется размер - соответственно идёт реаллокация памяти, а поскольку вы этот процесс не контролируете то он может идти как угодно - этим может управлять glibc или jemalloc или ещё что у вас в системе стоит. от этого сильно разная фрагментация памяти. что делать - заботиться о ценном ресурсе (пямяти). https://www.softwareverify.com... nightmare/
0
|
|||||||||||
|
4 / 4 / 2
Регистрация: 13.11.2014
Сообщений: 108
|
|
| 27.09.2023, 13:23 [ТС] | |
|
В системе скорее всего будет glibc.
Что и как красивого можно сделать с malloc, memset и free я в принципе понимаю, НО я сейчас просто ищу способ оптимизации небольшой проги написанной ДО меня и с многочисленными использованиями такого рода векторов в функциях. И просто хотелось бы обойтись малыми жертвами при её переписывании, чтобы не перелопачивать и переосмысливать, не только код но и подход в реализации каждой из них, по сути изобретая заново. Хотелось бы просто найти способ сделать это как-то более лаконично. Чтобы например можно было просто проставить в конце каждой из таких функций что-то вроде free_alloc<&T_std::vector>hexCh и освободить память или как-то ещё подлезть к тому аллокатору и выцепить с него всё что нужно и закончить с этим делом.
0
|
|
|
267 / 199 / 30
Регистрация: 26.11.2022
Сообщений: 862
|
||||||||||||||||
| 27.09.2023, 13:25 | ||||||||||||||||
|
кстати к своей предыдущей программе я добавил ваш код
Кликните здесь для просмотра всего текста
при использовании jemalloc Кликните здесь для просмотра всего текста
при использовании glibc Кликните здесь для просмотра всего текста
попробуйте делать резерв памяти для векторов перед использованием
0
|
||||||||||||||||
|
Модератор
|
|||||||
| 27.09.2023, 13:32 | |||||||
0
|
|||||||
|
4 / 4 / 2
Регистрация: 13.11.2014
Сообщений: 108
|
|
| 27.09.2023, 13:35 [ТС] | |
|
Я так полагаю statm_t Statm = ReadStatm(); скрыт в #include "statistics.h" )
А можете хотя бы объяснить, что там скрыто?) Потому что у меня такого эффекта не наблюдается без него абсолютно)
0
|
|
|
Модератор
|
|
| 27.09.2023, 13:37 | |
|
Если известен размер вектора заранее то лучше не использовать push_back, либо использовать но предварительно сделав reserve.
Только вот строки могут внести свои тонкости, так как строка это по сути тот же вектор
0
|
|
|
267 / 199 / 30
Регистрация: 26.11.2022
Сообщений: 862
|
||||||
| 27.09.2023, 13:37 | ||||||
1
|
||||||
|
4 / 4 / 2
Регистрация: 13.11.2014
Сообщений: 108
|
|||||||||||||
| 27.09.2023, 13:47 [ТС] | |||||||||||||
|
Всё как было так и осталось. Добавлено через 3 минуты
И это кстати вполне резервируя память. Добавлено через 2 минуты Вот кстати полностью изменённый код в итоге:
0
|
|||||||||||||
|
267 / 199 / 30
Регистрация: 26.11.2022
Сообщений: 862
|
||
| 27.09.2023, 13:49 | ||
|
операционная система когда выделяет кусок памяти - обычно выделяет только адресное пространство а помере обращения к памяти выделает страницы в физической памяти. скорее всего вектор при резервиновании не просто запрашивает у ОС память но и размещает там что-то.
0
|
||
|
4 / 4 / 2
Регистрация: 13.11.2014
Сообщений: 108
|
||||||||||||||||||||||
| 27.09.2023, 14:02 [ТС] | ||||||||||||||||||||||
Добавлено через 4 минуты В принципе тогда можно предположить, что строки так весело разнесли там нули в ячейках, ok, попробуем их опять тогда обнулить:
0
|
||||||||||||||||||||||
|
Модератор
|
||||||
| 27.09.2023, 14:20 | ||||||
|
Выполните программу для размышления.
Добавлено через 3 минуты Я бы привел тут аналогию с динамическим двумерным массивом, только указатели заменил на объекты. Так вот первый двойной указатель (массив указателей) это вектор, а каждый элемент этого вектора, указатель, это строка. И управление памятью что в векторе что в строке не зависит от пользователя
0
|
||||||
|
фрилансер
6444 / 5637 / 1128
Регистрация: 11.10.2019
Сообщений: 14,994
|
||
| 27.09.2023, 14:29 | ||
|
Добавлено через 1 минуту и вообще, нужно сделать минимальный синтетический пример, где аллокация будет только у этого вектора. На этом примере и тестить пожирание озу
1
|
||
|
4 / 4 / 2
Регистрация: 13.11.2014
Сообщений: 108
|
|
| 27.09.2023, 16:37 [ТС] | |
|
0
|
|
|
4 / 4 / 2
Регистрация: 13.11.2014
Сообщений: 108
|
|
| 28.09.2023, 10:56 [ТС] | |
|
Короче загадка "дыры в заборе" разгадана)
Вектор как таковой правильно работал и вполне себе освобождался при выходе из функции и обычный .clear() более чем отрабатывал. Весь фокус мы потом имели именно в std::string в векторе) По сути именно там и происходит утечка в ОП, когда получаем, что вектор вроде как и "освободился от своих элементов", а в тоже время теперь эти элементы привязались к тому, что скрывается под капотом у строк и никак не желают с этим расстаться) Проверить это достаточно просто прописав в вектор int. Нуу а теперь поправить код можно будет парочкой грамотных автозамен и немного ручного труда) Всем спасибо за советы и подсказки, а также ChatGPT за то, что показала ещё приколдесину с использованием std::shared_ptr и std::unique_ptr, кстати потом получше очищает память) ...а я её знатно помучал ![]() Добавлено через 2 минуты //P.S. модератор пометьте тогда моё предыдущее сообщение как ответ)
0
|
|
|
фрилансер
6444 / 5637 / 1128
Регистрация: 11.10.2019
Сообщений: 14,994
|
|
| 28.09.2023, 10:58 | |
|
0
|
|
|
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
|
|
| 28.09.2023, 11:06 | |
|
КиберСталкер21, честно говоря вы занимаетесь ерундой. Показания "системного монитора" еще нужно правильно трактовать.
Никакого перерасхода памяти у вас не происходит, просто если система будет постоянно гонять страницы (занятые аллокатором вашей программы) туда сюда, то будет только хуже. Поэтому аллокаторы не спешат сразу отдавать их системе, потому что есть немаленькая вероятность, что они понадобятся снова. А запрос новой страницы - это существенное время (по сравнению с использованием уже предоставленной ранее). К тому же в системе с виртуальной памятью в принципе нельзя точно сказать сколько действительно физической памяти сейчас занято. Те цифры, которые вы видите, - это виртуальные цифры. Они обозначит лишь то, что ваша программа технически сейчас может использовать столько-то байт памяти, а действительно ли она их использует эта информация не отражает. Почитайте для общего понимания: https://ru.wikipedia.org/wiki/Страничная_память
0
|
|
|
267 / 199 / 30
Регистрация: 26.11.2022
Сообщений: 862
|
|
| 28.09.2023, 11:15 | |
|
DrOffset, Современным программистам на с++ не надо лезть в тонкости работы системы, их освободили от ручного управления ресурсами. Поэтому ничего удивительного в том, что сейчас эти тонкости по управлению ресурсами мало кто понимает. Да и не требуется это уже в большинстве случаев.
0
|
|
| 28.09.2023, 11:15 | |
|
Помогаю со студенческими работами здесь
20
Освобождение памяти после динамического массива Освобождение памяти после использования трёхмерного массива
Резервирование памяти/освобождение памяти для трехмерного массива Избавиться от статических переменных Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
||||
|
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта
Симптом:
После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
|
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
|
Новый ноутбук
volvo 07.12.2025
Всем привет.
По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне:
Ryzen 5 7533HS
64 Gb DDR5
1Tb NVMe
16" Full HD Display
Win11 Pro
|
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
|
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
|
|
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов
На странице:
https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/
нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
|
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов.
. . .
|
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
|
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
|
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут.
В век Веб все очень привыкли к дизайну Single-Page-Application .
Быстренько разберем подход "на фреймах".
Мы делаем одну. . .
|