![]() |
1. Пользуйтесь тегами кода. - [code] ... [/code]
2. Точно указывайте язык, название и версию компилятора (интерпретатора).
3. Название темы должно быть информативным.
В описании темы указываем язык!!!
![]() ![]() |
![]() |
Lapp |
![]()
Сообщение
#1
|
![]() Уникум ![]() ![]() ![]() ![]() ![]() ![]() ![]() Группа: Модераторы Сообщений: 6 823 Пол: Мужской Реальное имя: Лопáрь (Андрей) Репутация: ![]() ![]() ![]() |
Несколько странной показалась мне работа с памятью..
Программа до смешного простая: в цикле аллоцирует память по элементам массива длины m. Каждый элемент - упакованный в структуру массив длины L. Цель программы - продемонстрировать ученику работу с динамической памятью.. В качестве самого первого приближения использую конструкцию с malloc(). Код, как результат импровизации, вышел неким гибридом C и C++ (так сказать, C+-)) Для наглядности я открыл TaskManager на закладке Performance. При m=2000 и L=106 я ожидал, что используемая память вырастет на 2 ГБ. Вставил задержку в цикл аллокации памяти, чтоб был наклон графика памяти. Думаю - сейчас мой ученик все увидит своими глазами. Запускаю прогу.. Ага, разбежался! ![]() Ход мысли такой: БЛИН!!!!!!!!!!!!!!!!! ГДЕ-ТО ОШИИИИИИБКА!! КЭШМЭРР!! Если ошибка, то при использовании взятой памяти будет сбой. Я добавляю в цикл присвоение константы случайному элементу внутреннего массива. Никаких сбоев - все пашет на ура.. Дальнейший ход мысли: НАДО ДЕБАГГИТЬ.. При отладке замечаю, что вся аллоцированная память инициализирована нулями.. ![]() О, СЧАСТЬЕ!! наконец-то моя программа начинает ЖРАТЬ ПАМЯТЬ! Сжирает ровно столько, сколько положено (а чудес я и не ждал)). Если же я делаю заполнение половины массива, то получаю половинный расход памяти. Первый пик - инициализавция всего массива (почти, то есть через один элемент), второй - только первой половины, третий - только второй половины. Вопрос, я полагаю, вы уже поняли. Кто занимается этим грязным бизнесом - компилятор или система? И вообще - какого, извините, черта? Компилятор - gcc (MinGW + C::B). Debug и Release ведут себя одинаково (в среде и без). OS - Windows 7 Pro 64 -------------------- я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой |
IUnknown |
![]()
Сообщение
#2
|
![]() a.k.a. volvo877 ![]() ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 1 013 Пол: Мужской Репутация: ![]() ![]() ![]() |
Цитата Вопрос, я полагаю, вы уже поняли. Кто занимается этим грязным бизнесом - компилятор или система? И вообще - какого, извините, черта? Вопросом на вопрос (мне можно ![]() А вообще, на RSDN была такая развлекуха: Развлечение - построить график заданной функции Сообщение отредактировано: IUnknown - 5.08.2011 9:46 |
Lapp |
![]()
Сообщение
#3
|
![]() Уникум ![]() ![]() ![]() ![]() ![]() ![]() ![]() Группа: Модераторы Сообщений: 6 823 Пол: Мужской Реальное имя: Лопáрь (Андрей) Репутация: ![]() ![]() ![]() |
Вопросом на вопрос (мне можно ![]() ![]() Цитата : А кто тебе сказал, что TaskManager показывает тебе аллоцированную malloc-ом память именно в Physical Memory? Виртуальную память проверял? malloc() увеличивает WorkingSet, то есть работает именно с виртуальной памятью (фактически, если мне память не изменяет, под Win функция malloc() = VirtualAlloc() + MEM_COMMIT). А уж потом, когда эта память начинает использоваться - тут уже начинает возрастать потребление памяти физической. Я, конечно, думал про своп ![]() ![]() Цитата А вообще, на RSDN была такая развлекуха: Развлечение - построить график заданной функции У меня тоже это мелькнуло в процессе ![]() -------------------- я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой |
IUnknown |
![]()
Сообщение
#4
|
![]() a.k.a. volvo877 ![]() ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 1 013 Пол: Мужской Репутация: ![]() ![]() ![]() |
Цитата но одна неувязка сбивала с толку эту мыслю.. А именно, что память обнулена. Не есть ли сие странно? Андрей, ну будь внимательнее: Цитата(Self) под Win функция malloc() = VirtualAlloc() + MEM_COMMIT и MSDN -> VirtualAlloc Function, которая гласит:Цитата MEM_COMMIT Что ж тут странного? Что функция WinAPI отрабатывает ровно так, как заявлено? Ну, может, ты и прав, странно это 0x1000 Allocates physical storage in memory or in the paging file on disk for the specified reserved memory pages. The function initializes the memory to zero. <...> ![]() Вот под *nix-ами - тут да, не обнуляется память при malloc(), только calloc()-ом... |
Lapp |
![]()
Сообщение
#5
|
![]() Уникум ![]() ![]() ![]() ![]() ![]() ![]() ![]() Группа: Модераторы Сообщений: 6 823 Пол: Мужской Реальное имя: Лопáрь (Андрей) Репутация: ![]() ![]() ![]() |
Что ж тут странного? Что функция WinAPI отрабатывает ровно так, как заявлено? Ну, может, ты и прав, странно это ![]() ![]() Цитата Вот под *nix-ами - тут да, не обнуляется память при malloc(), только calloc()-ом... Вот теперь все встало на свои места )), спасибо!+1 -------------------- я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой |
Lapp |
![]()
Сообщение
#6
|
![]() Уникум ![]() ![]() ![]() ![]() ![]() ![]() ![]() Группа: Модераторы Сообщений: 6 823 Пол: Мужской Реальное имя: Лопáрь (Андрей) Репутация: ![]() ![]() ![]() |
[offtop, хоть и не совсем]
Покрутивши это все в мозгах, я пришел к интересному (по крайней мере, для меня) выводу. Получается, что во время вызова malloc(), реального выделения памяти совершенно и не происходит. А происходит как бы то, что OS дает обещание выделить ее "по первому требованию". Точно так же, как банк (реальный, денежный) раздает займы клиентам - он не выдает наличные в тот же самый момент. И реально получается, что он тратит больше, чем имеет. Подсистема памяти в ответ на запрос на кусок К мегабайт возвращает адрес начала (вексель). Приложение может сразу начать использовать память, а может отложить это на какое-то время. Вот когда происходит реальное обращение по адресу внутри этого куска - тогда он реально отводится и инициализируется (обналичивается). То есть, что я хочу сказать, это то, что до того момента этот кусок реально не присутствует нигде. В самом деле - было бы слишком хлопотно расписывать нулями громадную область памяти на диске (в свопе), а потом считывать этот кусок в память.. Зачем?? достаточно хранить границы и.. - хотел сказать, 0, но потом подумал, что это тоже лишнее, поскольку инициализации другим числом просто не бывает ![]() Так вот, вывод, который отсюда следует, состоит в том, что аналогия между банком памяти и реальным денежным банком может пойти и дальше.. То есть система может выделить суммарно на запросы больше памяти, чем она реально имеет - как банк может выдать больше займов, чем может обеспечить ![]() .. но аналогия просматривается и еще дальше.. ![]() Вот такая аналогия )). [/offtop] -------------------- я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой |
![]() ![]() |
![]() |
Текстовая версия | 17.06.2025 23:52 |