Page 4 of 6

Re: Выделение памяти

Posted: Mon Oct 17, 2016 6:21 pm
by Pathoswithin
На самом деле и windows и linux делают точно так же. Разница в том, что у них есть файл подкачки, а у нас нет. А если файл подкачки отключить, то виндовые программы точно так же падают с ошибкой, если для них памяти не осталось.

Re: Выделение памяти

Posted: Mon Oct 17, 2016 6:23 pm
by 0CodErr
Pathoswithin, ну всё правильно, а раз у нас не так, значит и функции работы с памятью должны работать по-другому.

Re: Выделение памяти

Posted: Mon Oct 17, 2016 6:26 pm
by //DG
0CodErr wrote:Обсуждалось-то оно обсуждалось, а толку? Мне больше всего "понравился" 3-ий пункт алгоритма Serge viewtopic.php?f=2&t=3297&start=15#p65652
Ну разве кто-то будет использовать эту ОС для серьёзных вещей? Представьте, что от этого зависила бы работа дорогостоящего оборудования. Я уж не говорю про жизнь людей. А тут, понимаешь, Скрестить пальцы.
Так и представляю, пишет кто-то багрепорт, а Serge ему: "Пальцы скрещивали?" :)
Нет, не может. У другого процесса другое адресное пространство.
А я и не про это вовсе. Если 2 приложения зарезервируют каждый всю свободную память, то при обращении к ней рано или поздно у кого-то будет pagefault.
Ну,в принципе, все верно: прикинь сам: вариантов два: либо всегда при выделении закреплять физическую память сразу, тогда ты уже на этом этапе получишь ошибку "аут оф мемори, сорян". Либо так, как есть - мы гипотетически можем чуть больше памяти зарезервировать надеясь на то, что она не всем сразу понадобится. И как использовали - сразу отдали. В "серьезных" системах файл подкачки всегда подставит плечо, когда не хватает физических страниц.
Тот же ReactOS не имея подкачки падает в синий экран смерти, исчерпав физическую память.

Re: Выделение памяти

Posted: Mon Oct 17, 2016 6:28 pm
by //DG
0CodErr wrote:Pathoswithin, ну всё правильно, а раз у нас не так, значит и функции работы с памятью должны работать по-другому.
Можно я еще раз спрошу о корифеев: есть ли у вас флаг по типу MEM_COMMIT, который сразу закрепляет за тобой запрошенную память? А не тогда, когда произошло обращение?
Если нет, то жаль - это как раз был бы выход. Ты бы получил отпор уже на этапе запроса памяти.

Re: Выделение памяти

Posted: Mon Oct 17, 2016 6:32 pm
by Pathoswithin
Только так viewtopic.php?f=2&t=3297&start=19

0CodErr
Я тоже так думаю, но с другой стороны, есть программы, которые вообще не рассматривают вариант, что им памяти не дали. Да и не всегда есть варианты, кроме как покончить работу самоубийством.

Re: Выделение памяти

Posted: Mon Oct 17, 2016 6:39 pm
by //DG
Pathoswithin wrote:Только так viewtopic.php?f=2&t=3297&start=19
Почему нельзя его(закрепление по запросу) реализовать?
Да и не всегда есть варианты, кроме как покончить работу самоубийством.
Есть еще замечательный вариант: выдать милое сообщение "Недостаточно ресурсов, чтобы выполнить запрошенную операцию" и смотреть, как пользователь бесится. Фотошоп 32 любит так делать, когда виртуалка у него заканчивается.

Pagefault наверно можно поймать обработчиком исключений. И выдать это сообщение людям на потеху.

Re: Выделение памяти

Posted: Mon Oct 17, 2016 6:50 pm
by Serge
0CodErr
Ну разве кто-то будет использовать эту ОС для серьёзных вещей?
Если 2 приложения зарезервируют каждый всю свободную память, то при обращении к ней рано или поздно у кого-то будет pagefault.
В упор не вижу проблемы. Для серьёзных вещей нужные другие серьёзные вещи. Если я на своём рабочем компе захочу захочу выделить 128Гб в Win приложении, меня ждёт облом, потому что у меня нет 128Гб оперативки и своп маленький. Если программе не хватает памяти её можно прибить или перевести в зомби состояние. Сейчас работает первый вариант.

//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.

Re: Выделение памяти

Posted: Mon Oct 17, 2016 7:04 pm
by //DG
//DG
Вот как раз MEM_COMMIT и есть
Это кмк чуть-чуть другое: здесь идет речь о том, что выделяется кусок из теоретически возможного максимума (физическая + своп). Да, физическая не маппируется сразу - верно, но COMMIT гарантирует, что нам достается кусок из теоритически возможного: т.е. когда мы к нему обратимся, нам либо свободную физическую дадут, либо кого-нибудь в своп выкинут и нам отдадут его память.
Но суть та же: нам гарантируют, что запрошенный кусок будет. Нет? Если перевести в мир Колибри, то COMMIT не смапирует физическую память сразу НАМ, но и не даст кому-то другому ее себе смаппировать, потому мы COMMITом пообещали, что эта память будет и не будет никаких Fail'ов.
Т.е. если у нас есть, скажем, 100Мб свободной памяти, мы коммитим 30. Это значит, что никто больше не получит более 70ти. Когда мы к своей обратимся - получим ее. Или получим сразу. Я имел в виду именно эту гарантию, а не, маппируется ли она сразу, или же нам обещают кусок из свопа.

Re: Выделение памяти

Posted: Mon Oct 17, 2016 7:13 pm
by Serge
//DG
но COMMIT гарантирует, что нам достается кусок из теоритически возможного
Win на самом деле не даёт такой гарантии. В любой операционке это скорее обещание выделить, если будет возможность.

Re: Выделение памяти

Posted: Mon Oct 17, 2016 7:16 pm
by //DG
Serge wrote://DG
но COMMIT гарантирует, что нам достается кусок из теоритически возможного
Win на самом деле не даёт такой гарантии. В любой операционке это скорее обещание выделить, если будет возможность.
Не, ну кто бы спорил - есть ситуации, когда это не получится. И тем не менее, это якобы "обещание" много более сильное, чем колибриевское (система не даст тебе закоммитить больше, чем есть физической+свопа, и обломаться можно только если некого выгрузить). Тем более, что в отсутствие свопа мы моем гарантировать вообще железно: вот она свободная физическая, держи свой кусок.

Re: Выделение памяти

Posted: Sat Oct 22, 2016 5:35 pm
by 0CodErr
Подо что используется более 40 мегабайтов?
Spoiler:Image
Исходник
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.
Приложение
Unit1.kex (928 Bytes)
Downloaded 335 times

Re: Выделение памяти

Posted: Sat Oct 22, 2016 6:08 pm
by Serge
А что у тебя в автозагрузке ?

Re: Выделение памяти

Posted: Sat Oct 22, 2016 6:15 pm
by 0CodErr
Serge, а, так это на tmp-диск уходит.
Тогда ещё.
В документации сказано "Heap size is equal to total amount of free application memory."
А, получается, что на самом деле это не так?

Re: Выделение памяти

Posted: Sat Oct 22, 2016 7:56 pm
by Serge
Почему не так ? Почти 2 Гб свободных адресов.

Re: Выделение памяти

Posted: Sat Oct 22, 2016 8:50 pm
by 0CodErr
Serge, ну это же размер кучи 2 Гб, а памяти-то 256 Мб. Или в документации неточность?