Выделение памяти
-
На самом деле и windows и linux делают точно так же. Разница в том, что у них есть файл подкачки, а у нас нет. А если файл подкачки отключить, то виндовые программы точно так же падают с ошибкой, если для них памяти не осталось.
Pathoswithin, ну всё правильно, а раз у нас не так, значит и функции работы с памятью должны работать по-другому.
Ну,в принципе, все верно: прикинь сам: вариантов два: либо всегда при выделении закреплять физическую память сразу, тогда ты уже на этом этапе получишь ошибку "аут оф мемори, сорян". Либо так, как есть - мы гипотетически можем чуть больше памяти зарезервировать надеясь на то, что она не всем сразу понадобится. И как использовали - сразу отдали. В "серьезных" системах файл подкачки всегда подставит плечо, когда не хватает физических страниц.0CodErr wrote:Обсуждалось-то оно обсуждалось, а толку? Мне больше всего "понравился" 3-ий пункт алгоритма Serge viewtopic.php?f=2&t=3297&start=15#p65652
Ну разве кто-то будет использовать эту ОС для серьёзных вещей? Представьте, что от этого зависила бы работа дорогостоящего оборудования. Я уж не говорю про жизнь людей. А тут, понимаешь, Скрестить пальцы.
Так и представляю, пишет кто-то багрепорт, а Serge ему: "Пальцы скрещивали?"А я и не про это вовсе. Если 2 приложения зарезервируют каждый всю свободную память, то при обращении к ней рано или поздно у кого-то будет pagefault.Нет, не может. У другого процесса другое адресное пространство.
Тот же ReactOS не имея подкачки падает в синий экран смерти, исчерпав физическую память.
Можно я еще раз спрошу о корифеев: есть ли у вас флаг по типу MEM_COMMIT, который сразу закрепляет за тобой запрошенную память? А не тогда, когда произошло обращение?0CodErr wrote:Pathoswithin, ну всё правильно, а раз у нас не так, значит и функции работы с памятью должны работать по-другому.
Если нет, то жаль - это как раз был бы выход. Ты бы получил отпор уже на этапе запроса памяти.
Только так viewtopic.php?f=2&t=3297&start=19
0CodErr
Я тоже так думаю, но с другой стороны, есть программы, которые вообще не рассматривают вариант, что им памяти не дали. Да и не всегда есть варианты, кроме как покончить работу самоубийством.
0CodErr
Я тоже так думаю, но с другой стороны, есть программы, которые вообще не рассматривают вариант, что им памяти не дали. Да и не всегда есть варианты, кроме как покончить работу самоубийством.
Почему нельзя его(закрепление по запросу) реализовать?Pathoswithin wrote:Только так viewtopic.php?f=2&t=3297&start=19
Есть еще замечательный вариант: выдать милое сообщение "Недостаточно ресурсов, чтобы выполнить запрошенную операцию" и смотреть, как пользователь бесится. Фотошоп 32 любит так делать, когда виртуалка у него заканчивается.Да и не всегда есть варианты, кроме как покончить работу самоубийством.
Pagefault наверно можно поймать обработчиком исключений. И выдать это сообщение людям на потеху.
0CodErr
//DG
Вот как раз MEM_COMMIT и есть
В упор не вижу проблемы. Для серьёзных вещей нужные другие серьёзные вещи. Если я на своём рабочем компе захочу захочу выделить 128Гб в Win приложении, меня ждёт облом, потому что у меня нет 128Гб оперативки и своп маленький. Если программе не хватает памяти её можно прибить или перевести в зомби состояние. Сейчас работает первый вариант.Ну разве кто-то будет использовать эту ОС для серьёзных вещей?
Если 2 приложения зарезервируют каждый всю свободную память, то при обращении к ней рано или поздно у кого-то будет pagefault.
//DG
Вот как раз MEM_COMMIT и есть
MEM_COMMIT
0x00001000
Allocates memory charges (from the overall size of memory and the paging files on disk) for the specified reserved memory pages. The function also guarantees that when the caller later initially accesses the memory, the contents will be zero. Actual physical pages are not allocated unless/until the virtual addresses are actually accessed.
Это кмк чуть-чуть другое: здесь идет речь о том, что выделяется кусок из теоретически возможного максимума (физическая + своп). Да, физическая не маппируется сразу - верно, но COMMIT гарантирует, что нам достается кусок из теоритически возможного: т.е. когда мы к нему обратимся, нам либо свободную физическую дадут, либо кого-нибудь в своп выкинут и нам отдадут его память.//DG
Вот как раз MEM_COMMIT и есть
Но суть та же: нам гарантируют, что запрошенный кусок будет. Нет? Если перевести в мир Колибри, то COMMIT не смапирует физическую память сразу НАМ, но и не даст кому-то другому ее себе смаппировать, потому мы COMMITом пообещали, что эта память будет и не будет никаких Fail'ов.
Т.е. если у нас есть, скажем, 100Мб свободной памяти, мы коммитим 30. Это значит, что никто больше не получит более 70ти. Когда мы к своей обратимся - получим ее. Или получим сразу. Я имел в виду именно эту гарантию, а не, маппируется ли она сразу, или же нам обещают кусок из свопа.
//DG
Win на самом деле не даёт такой гарантии. В любой операционке это скорее обещание выделить, если будет возможность.но COMMIT гарантирует, что нам достается кусок из теоритически возможного
Не, ну кто бы спорил - есть ситуации, когда это не получится. И тем не менее, это якобы "обещание" много более сильное, чем колибриевское (система не даст тебе закоммитить больше, чем есть физической+свопа, и обломаться можно только если некого выгрузить). Тем более, что в отсутствие свопа мы моем гарантировать вообще железно: вот она свободная физическая, держи свой кусок.Serge wrote://DGWin на самом деле не даёт такой гарантии. В любой операционке это скорее обещание выделить, если будет возможность.но COMMIT гарантирует, что нам достается кусок из теоритически возможного
Подо что используется более 40 мегабайтов?ИсходникПриложение
Spoiler:
Spoiler:
Code: Select all
Unit Unit1;
(* -------------------------------------------------------- *)
Interface
(* -------------------------------------------------------- *)
Type
Dword = Cardinal;
Var
hConsole: Pointer;
ConsoleInit: Procedure(WndWidth, WndHeight, ScrWidth, ScrHeight: Dword; Caption: PChar); StdCall;
ConsoleExit: Procedure(bCloseWindow: Cardinal); StdCall;
printf: Function(Const Format: PChar): Integer; CDecl VarArgs;
(* -------------------------------------------------------- *)
Procedure Main; Forward;
Procedure ThreadTerminate; Forward;
Function LoadLibrary(Path: PChar): Pointer; StdCall; Forward;
Function GetProcAddress(hLib: Pointer; ProcName: PChar): Pointer; StdCall; Forward;
Function HeapCreate: Cardinal; Forward;
Function HeapAllocate(Bytes: Cardinal): Pointer; StdCall; Forward;
Function HeapFree(MemPtr: Pointer): Cardinal; StdCall; Forward;
Function GetFreeMemory: Dword; Forward;
Function GetAvailableMemory: Dword; Forward;
(* -------------------------------------------------------- *)
Implementation
(* -------------------------------------------------------- *)
Procedure Main();
Var
HeapSize: Dword;
FreeMemory: Dword;
AvailableMemory: Dword;
MemPtr: Pointer;
Begin
hConsole := LoadLibrary('/sys/lib/console.obj');
ConsoleInit := GetProcAddress(hConsole, 'con_init');
ConsoleExit := GetProcAddress(hConsole, 'con_exit');
printf := GetProcAddress(hConsole, 'con_printf');
ConsoleInit($FFFFFFFF, $FFFFFFFF, $FFFFFFFF, $FFFFFFFF, 'Test');
FreeMemory := GetFreeMemory();
AvailableMemory := GetAvailableMemory();
HeapSize := HeapCreate();
printf('Free memory = %d kilobytes.'#10, FreeMemory);
printf('Available memory = %d kilobytes.'#10, AvailableMemory);
If HeapSize = 0 Then
printf('HeapCreate Error!'#10)
Else Begin
printf('Heap created. HeapSize = %d bytes.'#10, HeapSize);
MemPtr := HeapAllocate(FreeMemory * 1024);
If MemPtr = nil Then
printf('HeapAllocate Error!'#10)
Else
printf('Allocated %d kilobytes. Pointer to memory = %#x'#10, FreeMemory, MemPtr);
If HeapFree(MemPtr) = 0 Then
printf('HeapFree Error!'#10)
Else
printf('Memory freed.'#10);
End;
ConsoleExit(0);
ThreadTerminate;
End;
(* -------------------------------------------------------- *)
Function HeapCreate: Cardinal;
Asm
push ebx
mov eax, 68
mov ebx, 11
int 64
pop ebx
End;
(* -------------------------------------------------------- *)
Function HeapAllocate(Bytes: Cardinal): Pointer;
Asm
push ebx
mov eax, 68
mov ebx, 12
mov ecx, Bytes
int 64
pop ebx
End;
(* -------------------------------------------------------- *)
Function HeapFree(MemPtr: Pointer): Cardinal;
Asm
push ebx
mov eax, 68
mov ebx, 13
mov ecx, MemPtr
int 64
pop ebx
End;
(* -------------------------------------------------------- *)
Function GetFreeMemory: Dword;
Asm
push ebx
mov eax, 18
mov ebx, 16
int 64
pop ebx
End;
(* -------------------------------------------------------- *)
Function GetAvailableMemory: Dword;
Asm
push ebx
mov eax, 18
mov ebx, 17
int 64
pop ebx
End;
(* -------------------------------------------------------- *)
Procedure ThreadTerminate();
Asm
mov eax, $FFFFFFFF
int 64
End;
(* -------------------------------------------------------- *)
Function GetProcAddress(hLib: Pointer; ProcName: PChar): Pointer;
Asm
push esi
push edi
push ebx
mov edx, hLib
xor eax, eax
test edx, edx
jz @end
mov edi, ProcName
mov ecx, $FFFFFFFF
repne scasb
mov ebx, ecx
not ebx
@next:
mov esi, [edx]
test esi, esi
jz @end
mov ecx, ebx
mov edi, ProcName
add edx, 8
repe cmpsb
jne @next
mov eax, [edx - 4]
@end:
pop ebx
pop edi
pop esi
End;
(* -------------------------------------------------------- *)
Function LoadLibrary(Path: PChar): Pointer;
Asm
push ebx
mov eax, 68
mov ebx, 19
mov ecx, Path
int 64
pop ebx
End;
(* -------------------------------------------------------- *)
End.
А что у тебя в автозагрузке ?
Serge, а, так это на tmp-диск уходит.
Тогда ещё.
В документации сказано "Heap size is equal to total amount of free application memory."
А, получается, что на самом деле это не так?
Тогда ещё.
В документации сказано "Heap size is equal to total amount of free application memory."
А, получается, что на самом деле это не так?
Почему не так ? Почти 2 Гб свободных адресов.
Serge, ну это же размер кучи 2 Гб, а памяти-то 256 Мб. Или в документации неточность?
Who is online
Users browsing this forum: Bing [Bot] and 2 guests