Page 1 of 6

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

Posted: Fri Jun 10, 2016 4:51 pm
by 0CodErr
Кто-нибудь с этим разбирался?
viewtopic.php?f=2&t=684&start=885#p53130

Может быть, Serge разъяснит, что там за такой очень хитрый менеджер памяти
viewtopic.php?f=2&t=684&start=930#p57580
там суть в том, что система даёт памяти больше, чем есть. А если в неё произойдёт запись, то начинаются PageFault-ы.

Re: Помогите новичку

Posted: Fri Jun 10, 2016 10:57 pm
by GerdtR
Кто-нибудь с этим разбирался?
viewtopic.php?f=2&t=684&start=885#p53130
При int 40h разве не происходит записи в стек следующего адреса? Как при call? Вроде как происходит.

Re: Помогите новичку

Posted: Sat Jun 11, 2016 6:05 pm
by Pathoswithin
Вроде как ещё и флаги сохраняются. То-есть 8 байт в стеке.

Re: Помогите новичку

Posted: Sat Jun 11, 2016 7:09 pm
by Serge
там суть в том, что система даёт памяти больше, чем есть. А если в неё произойдёт запись, то начинаются PageFault
Это спекулятивно оптимистичное поведение. Система позволяет программе зарезервировать из доступных адресов в userspace столько, сколько она просит. Физическая память выделяется после, страницами при обращении к адресам. Если в какой-то момент физической памяти не хватит, программа завершится со страничной ошибкой.

Re: Помогите новичку

Posted: Sat Jun 11, 2016 8:55 pm
by Pathoswithin
Кстати, винда тоже так делает, но у неё есть условно бездонный файл подкачки: не хватает — увеличивает.
Главный вопрос: в каких случаях программа берёт память и не использует её? Или конкретней: зачем нам этот баг эта сомнительная фича?

Re: Помогите новичку

Posted: Sun Jun 12, 2016 12:44 am
by Serge
Pathoswithin
Практически во всех программах, сложнее "Hello, world!" Там, кстати, тоже. Например программа рисует клиентскую область в битмап, чтобы избежать ненужных перерисовок. Если этот битмап фиксированного размера под текущий размер окна, его надо будет пересоздавать при растягивании окна. В этом случае лучше зарезервировать под битмап буфер максимально необходимого размера и управлять страничной памятью вручную.

Re: Помогите новичку

Posted: Sun Jun 12, 2016 10:20 am
by Pathoswithin
Ну надо сделать проверку, чтобы система хотя бы не выдавала больше памяти, чем есть на данный момент.

Re: Помогите новичку

Posted: Sun Jun 12, 2016 12:17 pm
by 0CodErr
GerdtR wrote:При int 40h разве не происходит записи в стек следующего адреса? Как при call? Вроде как происходит.
Pathoswithin wrote:Вроде как ещё и флаги сохраняются. То-есть 8 байт в стеке.
Да при чём здесь стек приложения?
Вот код с вершиной стека в нуле

Code: Select all

ORG 0
BITS 32
; --------------------------- ;
MENUET01       db 'MENUET01'
version        dd 1
program.start  dd START
program.end    dd END
program.memory dd END
program.stack  dd 0
program.params dd 0
program.path   dd 0
; --------------------------- ;
START:
        mov    eax, 15
        mov    ebx, 3
        int    64
        mov    eax, -1
        int    64
; --------------------------- ;
END:
Можете убедиться, что он работает, то есть, происходит перерисовка экрана, затем программа благополучно завершается.

Re: Помогите новичку

Posted: Sun Jun 12, 2016 12:40 pm
by Serge
Pathoswithin
Система не может выделить памяти больше, чем есть. Просто не надо путать резервирование адресов в userspace процесса и физ. память всей системы.

Re: Помогите новичку

Posted: Sun Jun 12, 2016 5:51 pm
by Pathoswithin
Если я правильно понимаю, по адресам памяти от FFFFFFFFh и ниже проецируется видеобуфер и доступ туда открыт всем программам.

Serge
Я не путаю, я спрашиваю проверяет ли система количество свободной физической памяти в момент резервирования адресов в userspace процесса?

Re: Помогите новичку

Posted: Sun Jun 12, 2016 6:44 pm
by Serge
Pathoswithin
Нет, не проверяет. Это лишнее. Некоторые применения 68.12 не требуют немедленного выделения физической памяти. Например открытие расшаренной памяти, загрузка длл, маппинг текстуры в драйвере. Широко применяемая malloc традиционно запрашивает память блоками большого размера при этом реально может использоваться 10%. Под стек в приложениях (binutils, Fplay и все остальные с newlib) резервируется 2Mб и т.д.

Re: Помогите новичку

Posted: Mon Jun 13, 2016 7:37 pm
by 0CodErr
Pathoswithin wrote:Если я правильно понимаю
А если нет :)
Spoiler:

Code: Select all

ORG 0
BITS 32
; --------------------------- ;
MENUET01       db 'MENUET01'
version        dd 1
program.start  dd START
program.end    dd END
program.memory dd END
program.stack  dd 0
program.params dd 0
program.path   dd 0
; --------------------------- ;
START
        mov    [0xFFFFFFFF], dword 0
        mov    eax, -1
        int    64
; --------------------------- ;
END
Spoiler:Image

Re: Помогите новичку

Posted: Mon Jun 13, 2016 9:13 pm
by Pathoswithin
General protection fault это не page fault. Попробуй FFFFFFF8h.

Re: Помогите новичку

Posted: Mon Jun 13, 2016 9:56 pm
by 0CodErr
Вот возьми сам и попробуй. Тебе полезно будет. А я результат знаю.

Re: Помогите новичку

Posted: Fri Jun 17, 2016 2:14 pm
by 0CodErr
Pathoswithin wrote:проверяет ли система количество свободной физической памяти в момент резервирования адресов в userspace процесса?
Serge wrote:Нет, не проверяет. Это лишнее.
Serge, ты так и не сказал, как можно решить эту проблему. Посмотри ещё раз на картинку в посте viewtopic.php?f=2&t=684&start=930#p57580 и скажи, как нужно в этом случае действовать приложению, чтобы не нарваться на PageFault. Ведь, как видно, памяти выделено явно больше, чем имеется, только приложения об этом не знают. Если можно, то пример кода, как можно обойти такую проблему.