WWW.ИСХОДНИКИ.РУ cpp.sources.ru
java.sources.ru web.sources.ru soft.sources.ru
jdbc.sources.ru asp.sources.ru api.sources.ru

  Форум на исходниках
  C / C++ / Visual C++
  Работа с памятью. Не может ли память стать решетом ?

СПРОСИТЬ  ОТВЕТИТЬ
профайл | регистрация | faq

Автор Тема:   Работа с памятью. Не может ли память стать решетом ?
DmitryRyvkin опубликован 15-12-2001 05:37 MSK   Click Here to See the Profile for DmitryRyvkin   Click Here to Email DmitryRyvkin  
Смотрел тут сурцы работы с памятью, возникли смутные подозрения...
Вот если я буду выделять куски памяти разной длины, потом СЛУЧАЙНО их удалять и т д (сохраняя ессно общее кол-во занятой), то не может ли она стать решетчатой ? Т е нужен скажем кусочек 1 кил, а в памяти 10000 кусков по 1 байту, но максимальный кусочек только скажем 990 байт ? Те памяти свободной до фига, да только не такая она... И кило мне не дадут без свопа :( Может такое вообще быть или это плод моего больного вображения ?
Нельзя эту граблю обойти разумными указателями ?
x опубликован 15-12-2001 09:17 MSK     Click Here to See the Profile for x  Click Here to Email x     
Бред оф сивый кэбл
маздай ее дефрагментирует
есть даже мессага WM_...
когда более 80 процентов времени уходит на дефрагментацию
tonik опубликован 16-12-2001 03:15 MSK     Click Here to See the Profile for tonik  Click Here to Email tonik     
Явление такое действительно имеет место быть, называется фрагментацией памяти и является большой головной болью для разработчиков ОС. Обойти на уровне приложений её нельзя, да и столкнуться довольно сложно, нужно занять ОЧЕНЬ много памяти, чтобы не было свободного куска нужного размера.
Flex Ferrum опубликован 16-12-2001 14:57 MSK     Click Here to See the Profile for Flex Ferrum  Click Here to Email Flex Ferrum     
x, tonik:
Не плохо было бы для начала в предмете разобраться. Дефрагментация памяти - отнюдь не головная боль ОС (по крайней мере защищенного режима) по той простой причине, что процессы, запущенные, например, под Windows, с физической памятью не работают. В их распоряжение отводится логическое адресное пространство (размером 4 Гб), распоряжаться которым они должны сами. По этому, это до сих пор головная боль разработчиков библиотек управления памятью для разработки программ (в частности, CRTL).
Organic опубликован 16-12-2001 19:09 MSK     Click Here to See the Profile for Organic  Click Here to Email Organic     
почему это головная боль? в MSVC 5.0 CRTL очень круто это дело забацано! мне понравилось
Flex Ferrum опубликован 16-12-2001 23:14 MSK     Click Here to See the Profile for Flex Ferrum  Click Here to Email Flex Ferrum     
Головная боль того, кто разрабатывает - ведь до красивой реализации еще дойти надо. Обычно это сложно.
server_mouse опубликован 16-12-2001 23:15 MSK     Click Here to See the Profile for server_mouse  Click Here to Email server_mouse     
x>есть даже мессага WM_...

Если мне не изменяет склероз, WM_... --- WindowMessage. Причём здесь окна?

DmitryRyvkin опубликован 17-12-2001 05:22 MSK     Click Here to See the Profile for DmitryRyvkin  Click Here to Email DmitryRyvkin     
Дык а все же может ? Дырчатой то стать ?
Копаюсь в сурцах, кажется Flex Ferrum прав.
Только я читал что в Дельфях работа с памятью круче сделана... (а может вообще у богланда) Интересно что именно у них круче, надо ли мне такое и вообще зачем козе баян...
x опубликован 17-12-2001 07:15 MSK     Click Here to See the Profile for x  Click Here to Email x     
нет люди вы мне определенно не нравитесь
каждый слушает только себя и разводит ламерский флуд вообще не по делу

Я ЖЕ СКАЗАЛ ЧТО НИКИКИХ ПРОБЛЕМ СО СЖАТИЕМ ПАМЯТИ БЫТЬ НЕ МОЖЕТ В ПРИНЦИПЕ
МАЗДАЙ САМ ЕЕ СЖИМАЕТ!!!!
ВСЕ ОСТАЛЬНОЕ=ДУРЬ

The WM_COMPACTING message is sent to all top-level windows when Windows detects more than 12.5 percent of system time over a 30- to 60-second interval is being spent compacting memory. This indicates that system memory is low.

WM_COMPACTING
wCompactRatio = wParam; // compacting ratio

Parameters

wCompactRatio

Value of wParam. Specifies the ratio of central processing unit (CPU) time currently spent by Windows compacting memory to CPU time currently spent by Windows performing other operations. For example, 0x8000 represents 50 percent of CPU time spent compacting memory.

Return Values

If an application processes this message, it should return zero.

Remarks

When an application receives this message, it should free as much memory as possible, taking into account the current level of activity of the application and the total number of applications running with Windows.

sergeil опубликован 17-12-2001 08:38 MSK     Click Here to See the Profile for sergeil  Click Here to Email sergeil     
x! А перевести на ru? :)
al опубликован 17-12-2001 00:35 MSK     Click Here to See the Profile for al  Click Here to Email al     
x абсолютно не понимает о чем говорит!
Сообщение то почылается, но программа в ответ на него дожна что-то делать! А что?
Фрагментация-действительно головная боль
для приложений, которые должны постоянно работать - серверов и т.п.

А проблема состоит а том, что после получения
указателя на блок памяти программа сохраняет
его во внутренних переменных - где именно - ОС знать в принципе не может. Поэтому дефрагментация возможна только при помощи самой прграммы - ОС может перемещать блоки памяти, но фрагментируется именно адресное пространство процесса!
Абстранктный пример:
Есть адресное пространство вв 4 байта :)
В начале программа получает три раза по одному байту:

char* p1 =GetMem(1); // OK! Адрес 0
char* p2 =GetMem(1); // OK! Адрес 1
char* p3 =GetMem(1); // OK! Адрес 2

После этого освобождается память p2

FreeMem(p2);

Теперю мы имеем следующую картину:
Адрес 0 - занят 1 байт
Адрес 1 - свободен
Адрес 2 - занят 1 байт
Адрес 3 - свободен

Итого - свободно 2 байта, но пди получи их

char* b4=GetMem(2); // ОШИБКА

Это и есть фрагментация адресного пространства.

Решение состоит в том, что после вызова GetMem(2) не только блок памяти по адресу 2 перешел на адрес 1, освобождая два байта в конце, но и в переменной p3 записалось новое значение - 'адрес 1'. В противном случае
программа перестанет правильно работать.

Решение проблемы - в отказе от работы с памятью 'напрямую' и использовании сборщиков мусора (как в Java и .Net) - т.е. Run-time библиотека или ОС должна уметь изменять
адреса, хранящиеся в указателях.


Таким образом что это головная боль языков программирования (C/C++ и т.п).

Alvengo опубликован 17-12-2001 18:33 MSK     Click Here to See the Profile for Alvengo  Click Here to Email Alvengo     
Вы бы, ребята, книжки что ли почитали какие, ибо природная сообразительность реальных знаний не всегда может заменить. Бред ведь городите. То, что вы называете "указателями", уже давно не указатели, а дескрипторы памяти. Поэтому дескриптор один и тот же, а физический адрес может прозрачно меняться, вплоть до сброса на диск... Эх, молодежь...
DemonM опубликован 17-12-2001 18:47 MSK     Click Here to See the Profile for DemonM  Click Here to Email DemonM     
ИМХО про WM_COMPACTING написано, что посредством етого сообщения система говорит что мамяти осталось мало, и окнам надо бы ее поменьше кушать. Кстати сам видел как ето происходит. Я потихоньку ел память и смотрел в диспетчер задач как она кончается, и в определенный момент заметил как все процессы, кроме моего, освободили примерно половину занятой ими памяти (ну я думаю кто сколько смог).
Flex Ferrum опубликован 17-12-2001 18:49 MSK     Click Here to See the Profile for Flex Ferrum  Click Here to Email Flex Ferrum     
Alvengo: А в C++ ты тоже дескрипторами пользуешься? Что-то я не помню, чтобы VirtualAlloc дескрипторы кому-то возвращал. И HeapAlloc иже с ним. Помниться мне, что дескрипторы возвращали такие функции, как GlobalAlloc да LocalAlloc, так они уже из употредления выходят. Да даже и в этом случае - ты пробовал этот дескриптор напрямую использовать? Долго потом ошибку искал?
Надо различать память, которой управляет системой, и память, которой управляет процесс. Одно к другому отношение имеет опосредованное. Процессу абсолютно не интересно, как и откуда ему будет выделена память. Системе же не интересно то, как выделенную память процесс будет использовать. В современных системах проблемы дефрагментации и сборки мусора практически не стоит - память квантуестя страницами и ими же выделяется. Процесс пользует эту память единым куском - отсюда и весь гемморой со сборкой мусора и дефрагментацией.
al опубликован 17-12-2001 19:12 MSK     Click Here to See the Profile for al  Click Here to Email al     
2Alvengo: char* в C++ - это дескрипрор?

Да, если ипользовать, например, только GlobalAlloc, GlobalLock и GlobalUnlock.
но в MSDN читаем:

The global and local functions supported for porting from 16-bit code, or maintaining source code compatibility with 16-bit Windows. The global and local functions are slower than other memory management functions and do not provide as many features. Therefore, new applications should use the heap functions. However, the global functions are still used with DDE and the clipboard functions.

Но VirtualAllock, HeapAlloc и т.п. возвращают LPVOID - в терминах C++ имеено указатель! - т.е. в C++ к ниму можно применять
арифметические операциии.

Пусть в моем пермере p1,p2,p3 и p4 - не указатели, а дескрипроы, и ОС в ответ
на вызов

char* b4=GetMem(2);

не выдаст ошибку 'Out of memory', а "сажмет" память, и выдаст дескрипрор 'Адрес 1'.

Теперь мы имеем следующую картину:
Адрес 0 - занят 1 байт
Адрес 1 - занят 2 байта
Адрес 2 - занят 1 байт
Адрес 3 - занят (хвост от Адрес 1)

Видите, наши 2 байта 'налезли' на 'Адрес 2'.
В принципе, если не выполнять операции над указателями, то можно и так. Но если будет такой код:


char* p1 =GetMem(1); // OK! Адрес 0
char* p2 =GetMem(1); // OK! Адрес 1
char* p3 =GetMem(1); // OK! Адрес 2
FreeMem(p2);
char* b4=GetMem(2); // пусть тоже ОК! Адрес 1

*p3='A';
p2[1]='B';

что теперю записано в *p3?
Откуда C++ программа узнает, что Адрес 1 + 1 = Адрес 3? нет, она тупо считает, что Адрес 1 + 1 = Адрес 2. В итоге *p3=='B'. Но мы то хотели другого.

В принципе ситуация фрагментации памяти в большинстве программ практически не может возникнуть - на это и расчитан "старый добрый" механизм указателей. Но если программа дожна работать "вечно" (например, Web-сервер) или обрабатывать очень большие объемы данных, то эта ситуация вполне возможна. Именно по этому в современных языках практически отказываются от указателей

stan опубликован 17-12-2001 21:36 MSK     Click Here to See the Profile for stan  Click Here to Email stan     
Народ, чем рассуждать на тему может или не может, наверное, лучше попробовать что-нибудь типа:
while(1){
int* a = new int[rand()%1000000];
int *b = new int[rand()%1000000];
delete[] a;
delete[] b;
Sleep(100);
}
(ну например). А потом по результатам этого спорить. Я сам еще не пробовал, но обязательно попробую, и вам советую.
DmitryRyvkin опубликован 18-12-2001 05:17 MSK     Click Here to See the Profile for DmitryRyvkin  Click Here to Email DmitryRyvkin     
2stan
Немного не так.
Надо создать что типа массива указателей,
и в цикле СЛУЧАЙНО присваивать случайному указателю кусочек памяти, а потом удалять также случайный указатель (те его память)
Все в цикле.
DmitryRyvkin опубликован 18-12-2001 05:17 MSK     Click Here to See the Profile for DmitryRyvkin  Click Here to Email DmitryRyvkin     
PS Счас попробую
x опубликован 18-12-2001 06:43 MSK     Click Here to See the Profile for x  Click Here to Email x     
да да да
в MSDN написали и оборжались а вы поверили

и да будет вам известно что LocalAlloc вызывает именно HeapAlloc=кто не верит go IDA

память и ежу понятно что выделяется 4k страницами

ну а если ты умудрился загадить своими кривыми руками 2Гб пространства твоего процесса=это твои проблеблемы=ты отстойный програмер

кста не знаю кто как а я всегда использую для памяти только HLOCAL

DmitryRyvkin опубликован 18-12-2001 07:23 MSK     Click Here to See the Profile for DmitryRyvkin  Click Here to Email DmitryRyvkin     
2x >ну а если ты умудрился загадить своими ?кривыми руками 2Гб пространства твоего процесса=это твои проблеблемы=ты отстойный програмер

Вопрос частично теоретический, частично познавательный. Удивляет разнообразие мнений по столь "железному вопросу"
Причем тут страницы ?
По int *pint = (int *) malloc (sizeof(int))
мне что, страница возвращается ?
Чего то я ни фига не понимаю.

Flex Ferrum опубликован 18-12-2001 10:01 MSK     Click Here to See the Profile for Flex Ferrum  Click Here to Email Flex Ferrum     
2х: Хотел бы я посмотреть на скорость работы проги, которая для каждого плевка просит память у системы... Ты хоть помнишь, в чем была разница между LocalAlloc и GlobalAlloc? И откуда у них ноги растут? То, что LocalAlloc вызывает внутри себя HeapAlloc - вполне логично. По той простой причине, что такого понятия как _локальный_хип_процесса_ в Win32 бульше не существует - а имитировать его как-то надо. Библиотечные менеджеры памяти для того и существуют, чтобы один раз попросить у системы большой кусок памяти, а потом резать его на части в соответствии с надобностью программы.
DemonM опубликован 18-12-2001 10:07 MSK     Click Here to See the Profile for DemonM  Click Here to Email DemonM     
Да блин легче прогу написать которая все это проверит, чем тут воду месить.
Alvengo опубликован 18-12-2001 14:18 MSK     Click Here to See the Profile for Alvengo  Click Here to Email Alvengo     
Орешек знаний тверд.... "char* в С++" это безусловно указатель, с ним можно производить арифметические операции (в пределах отведенной памяти!). Но это уровень языка, а не ОС, _фактически_ указателем в вашем понимании является только группа младших разрядов (смещение), а в старших записан дескриптор страницы (база), раздела или чего там еще... Это базовый принцип архитектуры _любых_ систем, использующих свопинг, который поддерживается аппаратно и ОСом. Именно это и позволяет скидывать на диск твою память так, что ты этого не замечаешь (ну кроме времени доступа, ессно)... Я путано объясняю, но в коротком сообщении и невозможно раскрыть все, о чем в институте нам читали целый семестр...
Valery опубликован 18-12-2001 15:19 MSK     Click Here to See the Profile for Valery  Click Here to Email Valery     
Вот ведь как! Незачем, оказывается придумывать всякие там стратегии управления памяти, мудрить с умными, ведущими и иже с ними указателями и прочая.... Умная система и так, оказывается, сама сгребет мусор, дефрагментирует память, которую одним куском выделила какому-нибудь _вечноработающему_ приложению, может писать вообще ничего не надо? :)
Люди! Ну, хоть когда спорите, перечитайте _все_ реплики своих оппонентов! Ответы там уже есть.
DemonM опубликован 18-12-2001 15:49 MSK     Click Here to See the Profile for DemonM  Click Here to Email DemonM     
кэш знаете ли .....
x опубликован 19-12-2001 07:03 MSK     Click Here to See the Profile for x  Click Here to Email x     
да кста
я тут малость проглючил насчет 2Г
тут не 2Г а гораздо больше
тут на каждый сеектор по 4Г
xKernel опубликован 19-12-2001 07:19 MSK     Click Here to See the Profile for xKernel  Click Here to Email xKernel     
Мне тут как-раз на днях довелось увидеть прогу которая при инициализации делала массив в 400 мег!!! Вот так бывает :)
maxvid опубликован 24-12-2001 06:37 MSK     Click Here to See the Profile for maxvid  Click Here to Email maxvid     
удивительные изречения тут прочитал:)))

вы бы еще попытались сделать так, чтоб malloc вам память выделял в кеше процессора :)))

когда вы просите блок памяти в N байт, вы получаете "адрес" начала блока.
этот "адрес" всего лишь смещение от начала сегмента, величина смещения от 0 до 2^32, а сегмент (в современных процессорах) это всего лишь описание памяти (размером соответственно до 4Гбайт).

вся физическая память (с позиции процессора и операционки) разделена на страницы размером 4кбайт. если к данным в некоторой странице происходит обращение, процессор!! (через описатель сегмента памяти) для данной страницы ставит отметочку 'использовалась'. для не используемых страниц процессор снимает эту отметочку.
если вдруг происходит обращение к "адресу" для которого небыло страницы и свободного места нет в физической памяти, то процессор генерирует прерывание (вызывает функцию операционной системы :) по которому операционка просматривает все страници и сбрасывает в своп те, которые давно не использовались, в описателе сброшенной страницы ставит отметочку 'в свопе' , и возвращает управление после перывания.
если вдруг происходит обращение к странице для которой стоит отметочка 'в свопе', процессор генерирует соответствующее прерывание, а операционка восстанавливает страницу из свопа.
существует несколько методик распределения страниц по котрым операционка управляет памятью.
(извиняюсь за идиотское изложение технических основ :)

если вы в своей программе запросили массив
int A[10000];
а используете только первые сто элементов, то остальная часть массива будет сброшена в своп (частями по 4к). при этом используемая часть массива какое-то время будет находиться в кеше(кешах) процессора. все это происходит без вашего ведома и согласия и вас не должно касаться до тех пор пока не начнете писать свою операционку.

Удачи.

СПРОСИТЬ  ОТВЕТИТЬ
Перейти:


E-mail | WWW.ИСХОДНИКИ.RU

Powered by: Ultimate Bulletin Board, Freeware Version 5.10a
Purchase our Licensed Version- which adds many more features!
© Infopop Corporation (formerly Madrona Park, Inc.), 1998 - 2000.