LINUX.ORG.RU

C++. Предсказуемость поведения менеджера памяти.


0

1

Проверять результат выполнения new/malloc и т.п. - это конечно полезно, но не так прикольно. Не переключайте канал!

Софтина изредка в несколько потоков вызывает new(), прося что-то в районе 1...2 МБ памяти. Подобные запросы случаются одновременно из 4 потоков. Результат вызова не проверяется. Железных ядер - 4 (на всех нижеописанных платформах).

На тестовой платформе с linux 3.4.9 с 32 Гб ОЗУ работала безупречно.

На тестовой платформе с win-7 с 16 Гб ОЗУ иногда валилась. Валилась с одинаковой вероятностью и на виртуалке с 4 Гб ОЗУ.

Казалось бы - 16 гигов! Параллельно фотошопов не загружено. Если смотреть на стандартный «график использования ресурсов», то уровень занятости памяти валяется в нижних 20%.

Почему может так происходить, что при наличии кучи свободной памяти изредка происходят такие обломы? Ясно, что в таком топике на форуме невозможно объяснить и понять логику такой хитрой штуки, как менеджер памяти какой-либо ОС. Но хотя-бы какими его свойствами это может объясняться? Какие причины гипотетически тут могут быть? Он работает асинхронно от вызовов выделения памяти? Вызов на выделение памяти не блокирующий и может произойти в «неудобное время» (идёт процесс переупорядочения свободных блоков) и будет отклонён? Занятость диспетчера памяти своими служебными задачами рассматривается как отказ, равнозначный отсутствию свободной памяти? Почему вызывающий поток не будет заблокирован, чтобы дождаться окончания служебных процедур, если они кратковременные?

Ответ на: комментарий от kiverattes

Виртуальная память может кончиться, если значение системной переменной, в которой лежит её свободный виртуальный объём дошло до нуля. Ваш Кэп

твой Кэп понимает между нормальной работой, и аварийным режимом? Если я говорю, что самолёт не может летать без крыльев, ты будешь с этим спорить?

нет. Виртуальная память становится резидентной в момент обращения.

Это системные тонкости, зависящие от ОС, а с точки зрения пользователя функции malloc()/new() и т.п. она никакой не «становится», а всегда является просто памятью.

К сожалению, эти тонкости необходимо учитывать, хотя-бы из-за того, что время обращения к(ещё или уже) виртуальной памяти и к (уже)физической может отличаться на несколько порядков. Причём даже в самом обычном, рабочем режиме. А вот вопрос поведения при исчерпании можно как раз не рассматривать, ибо это уже сбой _всей_ системы, и программа всё равно при всём желании никак на это повлиять не может. Если её OOM убил, то программа в принципе с этим ничего не сможет поделать. Посему _виртуальную_ память можно считать бесконечной, причём ::new так и делает обычно.

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

А что делать-то? Работа ведь сама делаться не будет! Вот так и получается, что подавляющее большинство научного софта — жуткий быдлокод, базирующийся на костылях и подпорках. Но лучше уж так, чем вообще никак!

memset'ит всю свою память, даже она не нужна

Я, в отличие от хроморазрабов, выделяю именно столько памяти, сколько мне нужно!

Память освобождается «сама», деструктором

Или не освобождается ☺

Ты же не делаешь списки/стеки/строки на php?

Я пыхпыхом вообще не пользуюсь! У меня веб на сишечке же!

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

А в программах, задача которых быстро выполнить вычисления и сдохнуть, можно вообще не осбождать память.

ага, а потом твой код будет частью какого-нить браузера/демона, и доставит твоим юзерам немало весёлых минут и часов. ИЧСХ плеваться будут в создателя браузера/демона, а не в тебя...

ИМХО, можно как выше говорилось выделить себе скажем гиг памяти, и всё там аллоцировать. А потом весь этот гиг вернуть. По времени это также быстро, но намного надёжнее твоего быдлокода.

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

Я, в отличие от хроморазрабов, выделяю именно столько памяти, сколько мне нужно!

пойми правильно хроморазрабов: их поделие само выполняет код, причём возможно намеренно вредоносный, и в 9и случаях из 10 — явный быдлокод (жабаскрипт например). Если-бы у нас был простой HTML, то проблемы-бы с памятью (и со временем) не было. Но с этим быдлокодом всё становится печально и непредсказуемо.

Или не освобождается ☺

почему-же у тебя «не освобождается»? Ты не имеешь привычки делать деструкторы виртуальными? Забыл определить operator=()? В чём твоя проблема-то?

Я пыхпыхом вообще не пользуюсь! У меня веб на сишечке же!

посмотреть можно?

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

пойми правильно хроморазрабов

А почему же огнелис нормально работает? А сраный хромой уже на десяти открытых вкладках начинает тупить и падать?

почему-же у тебя «не освобождается»?

Потому что я плюсы не знаю и знать не хочу ;)

посмотреть можно?

В моем профиле (старом) указан был линк на сосфорж. Там можно посмотреть. Как ни странно, весь этот быдлокод работает!

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

Не хочу тебя игнорить. Тебе иногда отвечают нормальные люди, и игнор будет касаться и их постов.

А вот тебе-бы неплохо отвечать по теме. Мы же не в толксах? Или промолчать, если мой пост ты не осилил, и счёл потому «бредом», или меня заигнорить. В любом случае, твой бред про «Нибиру» я склонен считать сливом.

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

А почему же огнелис нормально работает? А сраный хромой уже на десяти открытых вкладках начинает тупить и падать?

Потому что лис не форкается как ненормальный.

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

А почему же огнелис нормально работает? А сраный хромой уже на десяти открытых вкладках начинает тупить и падать?

Ну есть два способа написания кода:

1. корпорация XYZ нанимает N программистов, они пишут продукт ZYX, далее этот продукт продаётся. При этом программисты идут заниматься своими делами (новыми проектами), а вот код поддерживают дешёвые IT обезьяны. Какой-бы не был хороший код изначально, но время идёт, и исправить всё только неквалифицированными костылями не получается. Код ветшает, но всем пофиг. Так мы(пользователи) видим продукт ZYX, который скатывается в унылое сраное говно. Причём совсем не важно, как «хороша» XYZ. Если проект закрыт, конец немного предсказуем.

2. OpenSource. Это тоже не без минусов, но во всяком случае, СПО проекты в УГ скатываются много реже. Оттуда эти N программистов не уходят.

Потому что я плюсы не знаю и знать не хочу ;)

ну не знай. Это не повод говорить о том, что на нём нельзя писать хороший код. Можно. Сила C++ именно в гибкости, например я не считаю, что для твоего веба подойдёт сишечка с её отсутствием строк как таковых (glib для веба явно недостаточна), да и STL тоже для веба плохой ИМХО вариант, ибо STL «слишком хорош» для веба. Там будет идеальным подход пыха, когда у тебя есть универсальная структура данных (php-массив) и универсальные строки. Это можно сделать на C++, но без STL, и именно на плюсах. (можно по другому, но хуже).

Можно, но не нужно, ибо php уже есть.

ЗЫЖ мне лениво твой профиль искать...

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

значит видно не судьба. Игнорь меня на уровне подсознания. (:

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

Надо разобраться понятиями. Вы про аварию приложения или ОС говорите, когда говорите «авария»? С точки зрения ОС - штатная ситуация достижения заранее установленного предела, с точки зрения приложения - авария, да, может быть.

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

с точки зрения приложения - авария, да, может быть.

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

И важно понимать, что нехватка виртуальной памяти вообще говоря глобальная, и говорить про «нехватку виртуальной памяти для приложения» попросту == делить на ноль. С т.з. приложения, у него 2**64-1 байтов виртуальной памяти, т.е. практически бесконечно. Т.е. не имеет лимитов никаких. IRL естественно имеет конечно, но это уже «тонкости реализации». Их как раз НЕ нужно учитывать, если у тебя должен получится годный кроссплатформенный код.

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

Уточним тогда - какую конкретно ситуацию вы называете аварией? Возврат NULL из malloc()? throw bad_alloc из new()?

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

Исчерпание памяти. Это когда код обращается к ячейке 12345, а эта ячейка не только не распределена, но и её распределение невозможно потому, что физическая память кончилась. Это авария. И эта авария обычно случается намного раньше, чем твой malloc вернёт NULL (или new бросит исключение)

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

А что, MSVC у нас уже ОС?

у нас это win-only программа. Как в вашей альтернативной реальности — я не в курсе.

А Linux 3.x?

а ты подумай...

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

у нас это win-only программа

Если что, win-only совершенно не обязательно MSVC.

а ты подумай...

Дурачкам объяснять азы не вижу смысла, отвечу только на первоначальный вопрос, сдела вид что задан не совершенно безграмотно. Да, в разных системах ::new может делать один и тот же код, и да, на одной системе ::new может делать разный код.

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

у нас это win-only программа

Если что, win-only совершенно не обязательно MSVC.

если что, то то, что мокрое, не обязательно вода. Но если вода, то мокрая.

Дурачкам объяснять азы не вижу смысла, отвечу только на первоначальный вопрос, сдела вид что задан не совершенно безграмотно. Да, в разных системах ::new может делать один и тот же код, и да, на одной системе ::new может делать разный код.

роль К.О. тебе не очень идёт. Факт в том, что в реальной жизни, код ::new из gcc сильно отличается от кода из MSVC. По этой причине, один и тот же C++ быдлокод собранный ТСом в венде глючит совсем по другому, чем в Linux. Посему ты не прав в том, что «от ОС это не зависит». Зависит.

ЗЫЖ и да, если-бы ТС умел-бы грамотно задавать вопросы, он бы и не спрашивал. Что-бы задать грамотный вопрос, нужно знать правильный ответ. Но какой смысл тогда спрашивать?

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

Но если вода, то мокрая.

Нет. Есть wine.

Зависит.

Для совсем тугих: менеджер памяти - часть стандартной библиотеки. От ОС он не зависит никак.

Если ещё и память дырявая, речь шла вот про это абсолютно безграмотный набор слов от ТС:

менеджер памяти какой-либо ОС

ЗЫЖ и да, если-бы ТС умел-бы грамотно задавать вопросы, он бы и не спрашивал. Что-бы задать грамотный вопрос, нужно знать правильный ответ. Но какой смысл тогда спрашивать?

Ты кажется начинаешь что-то понимать...

slovazap ★★★★★
()
Последнее исправление: slovazap (всего исправлений: 1)
Ответ на: комментарий от slovazap

Для совсем тугих: менеджер памяти - часть стандартной /библиотеки. От ОС он не зависит никак.

Их два, один внутри стдлиб, второй в ОС.

kiverattes ★☆
() автор топика
Ответ на: комментарий от slovazap

Для совсем тугих: менеджер памяти - часть стандартной библиотеки. От ОС он не зависит никак.

facepalm...

Блжад! В разных ОС разные стандартные либы и разные менеджеры. Что тут непонятного? И в MSVC своё, родное, от мысы. Для некоторых функций даже сырцы есть (были раньше, сейчас не знаю). Ты так утверждаешь, как если-бы ты утверждал, что конструкция и размер колеса не зависит от того, колесо это от камаза, или от запорожца. Может в твоей альтернативной реальность и не зависит, а вот у меня они разные, как по габариту, так и конструктивно.

Если ещё и память дырявая, речь шла вот про это абсолютно безграмотный набор слов от ТС:

менеджер памяти какой-либо ОС

просто ты его не смог понять, а я осилил. Очевидно, он имел ввиду менеджер из glibc vs менеджер из поставки рантайма MSVC libc. Они, между прочим, очень сильно отличаются, и ведут себя похоже лишь в первом приближении. Особенно если им скормить быдлокод.

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

Их два, один внутри стдлиб, второй в ОС.

это как раз от реализации зависит. В старом MSVC ЕМНИП был свой велосипед. А вот в теперешнем glibc AFAIK вообще менеджера нет. То, что там есть, это лишь обёртка над mmap(2) (поправьте меня, если я не прав).

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

Их два, один внутри стдлиб, второй в ОС

Написана чушь. Что опять имеется в виду под ОС? Предрекаю что имеется в виду либо менеджер памяти использующийся в ядре, который к данной теме никаким боком, либо механизм виртуальной памяти, который ортогонален.

Блжад!

Последняя попытка: софт собранный MSVC и mingw на win32 будет иметь совершенно разные аллокаторы. Потом эти же бинарники (статически собранные) можно будет запустить под wine, и их разные аллокаторы останутся. Читай по губам: никакой. зависимости. от. ОС.

это как раз от реализации зависит. В старом MSVC ЕМНИП был свой велосипед. А вот в теперешнем glibc AFAIK вообще менеджера нет. То, что там есть, это лишь обёртка над mmap(2) (поправьте меня, если я не прав).

Ты неправ, и похоже ты ещё больше плаваешь в материале чем ТС. «Обёртка над mmap» и есть менеджер памяти, потому что именно в ней содержится вся тяжёлая логика. Выделение страниц - тривиальная операция, нетривиальны алгоритмы размещения в них данных разных размеров, учитывающие мнешнюю и внутреннюю фрагментацию, хранящие метаданные типа карты свободных фрагментов, умеющие эти страницы обратно отдавать системе и т.д. и т.п., и всё это в условиях многопоточности. А так аллокаторы на всех поголовно современных системах взаимодействуют с ядром одинаково и все являются «обёртками над mmap».

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

Последняя попытка: софт собранный MSVC и mingw на win32 будет иметь совершенно разные аллокаторы.

я и нее утверждал, что будут разные. Разные будут и в разных Linux'ах.

Потом эти же бинарники (статически собранные) можно будет запустить под wine, и их разные аллокаторы останутся. Читай по губам: никакой. зависимости. от. ОС.

при чём тут wine? Разная ОС == разный рантайм == разный аллокатор. Wine это тоже эмулятор, только не венды, а вендового API. И если я прав(до сих пор), и сейчас алллокатор это часть рантайма, то да, в wine он свой, из маздая останется. Хотя работать он будет очевидно иначе, ибо никакого WinAPI там нет, а есть только его эмуляция.

И да, возьми дизассемблер, и посмотри сам, мне лень в этом говне ковыряться.

А так аллокаторы на всех поголовно современных системах взаимодействуют с ядром одинаково и все являются «обёртками над mmap».

вот только «mmap» везде разный. Как и сами аллокаторы. Единственная обёртка, которая везде одинаковая, это ::new. Всё осталльно зависит от всего остального, в т.ч. конечно же и от ОС.

2анонимус: ваше мнение очень важно для нас. Но отвечать мне тебе лениво.

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

Разная ОС == разный рантайм == разный аллокатор

Я даже показал на примере что это не так. Спорить дальше будет только идиот.

Wine это тоже эмулятор

Wine расшифровывается как он расшифровывается именно потому что он не эмулятор, а реализация API.

Хотя работать он будет очевидно иначе, ибо никакого WinAPI там нет, а есть только его эмуляция.

Именно WinAPI там и есть. Реализация другая, но, например, взяв dll'ки от венды или запустив статически собранный на винде бинарник получите такую же.

вот только «mmap» везде разный

mmap везде одинаковый - это базовый примитив работы с VM из userspace и фактически стандартный системный вызов. Он всего лишь интерфейс для получения страниц, рулит всем аллокатор.

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