Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2007.01.28;
Скачать: [xml.tar.bz2];

Вниз

Чем отличаются GlobalAlloc от VirtualAlloc? И про PChar.   Найти похожие ветки 

 
Vovan #2   (2007-01-04 19:29) [0]

Собственно, в том и вопрос: чем отличаются GlobalAlloc от VirtualAlloc? Требуется либо объяснение на доступном уровне, либо прямая ссылка на текст с объяснением.

Что за штука такая PChar, что люди объявляют Buf: array of PChar, а потом делают buf := VirtualAlloc(параметры)???


 
ors_archangel ©   (2007-01-04 19:44) [1]

Local/GlobalAlloc выделяет блоки памяти в куче процесса, а VirtualAlloc работает выделяет страницы в адресном пространстве процесса, т.о. первая более высокого уровня, чем вторая.


 
ors_archangel ©   (2007-01-04 19:47) [2]

И про PChar: даже судя только по названию понятно, что это point to char, ничего необычного, кроме нек расширенных возможностей, которые в случае buf := VirtualAlloc не задействованы, т.е. buf здесь мог бы быть с таким же успехом и buf: array of Integer


 
Loginov Dmitry ©   (2007-01-04 20:08) [3]

> люди объявляют Buf: array of PChar


Неужели люди и вправду подобное объявляют?


 
MetalFan_pda   (2007-01-04 20:11) [4]

[1]
т.о. первая более высокого уровня, чем вторая.
причем тут уровни? у процесса есть куча,а есть ВАП. под разные задачи. почитайте Рихтера например,прежде чем неверные,имхо,вещи писать ;)


 
ors_archangel ©   (2007-01-04 20:40) [5]


> MetalFan_pda   (04.01.07 20:11) [4]

Расшифруй, что неправильно: я сказал, что VirtualAlloc нискоуровневней GlobalAlloc. Не читал Рихтера, но понятно, что GlobalAlloc является частью менеджера кучи процесса, т.о. он, например, может быть реализован через VirtualAlloc, который непосредственно работает в ВАП процесса, поэтому я пишу, что VirtualAlloc на уровне ниже GlobalAlloc, имеет смысл? Безусловно разные задачи, но, имхо, всё верно: это нормально, когда низкоуровнеыый интерфейс A и высокоуровневый интерфейс B, реализованный посредством A, имеют разное применение


 
Vovan #2   (2007-01-04 21:00) [6]

А в чём различие применений? Дело в том, что рассматриваю два примера выделения буфера для одной задачи и в одном VirtualAlloc, а другом GlobalAlloc.

В этом случае автор сделал выравнивание по странице памяти, что-ли.

var Buf : array [0..1] of PChar;

 buf[0] := VirtualAlloc(nil,(BlockSize*4+si.dwPageSize-1) div si.dwPagesize * si.dwPageSize, MEM_RESERVE or MEM_COMMIT, PAGE_READWRITE);
 buf[1] := PChar(LongInt(buf[0]) + BlockSize); // x


В строке x мне было непонятно разнообразие приведений. Адрес первого буфера от приводит LongInt, а в итоге хочет PChar. И нужны ли приведения?

А вот второй случай:


 hBuf := GlobalAlloc(GMEM_MOVEABLE and GMEM_SHARE, BufLen);
 Buf := GlobalLock(hBuf);


Кстати, зачем нужно делать GlobalLock?

Теперь мне непонятно, зачем вообще связываться с VirtualAlloc или GlobalAlloc, есть GetMem? Результат ведь один и тот же - указатель на выделенную в памяти область.


 
MetalFan ©   (2007-01-04 22:28) [7]


> ors_archangel ©   (04.01.07 20:40) [5]


да, в общих чертах все верно) сорь за не совсем верные утверждения.
в виртуальной памяти процесса выделяется место и под кучи и под стеки потоков.
только это все скрыто от пользователя АПИ. вроде так.


 
GrayFace ©   (2007-01-04 22:44) [8]

Теперь мне непонятно, зачем вообще связываться с VirtualAlloc или GlobalAlloc, есть GetMem? Результат ведь один и тот же - указатель на выделенную в памяти область.
Грубо говоря, VirtualAlloc выделяет только большие блоки памяти, GetMem - любые. Не задумываясь используй GetMem, а для массивов SetLength. Работа напрямую с VirtualAlloc может понадобиться, пожалуй, только для эффективности в некоторых случаях.
У GlobalAlloc своя специфика. Например, в буфер обмена можно "положить" только память, выделенную при помощи GlobalAlloc. Наверное, это в твоем примере и делается.


 
MetalFan ©   (2007-01-04 23:47) [9]


> GrayFace ©   (04.01.07 22:44) [8]

почитайте же наконец спец.литературу или на худой конец MSDN!!!

> VirtualAlloc выделяет только большие блоки памяти

да ну что вы говорите?!
lpvResult := VirtualAlloc( nil, // next page to commit
                                 1,         // page size, in bytes
                                 MEM_COMMIT,         // allocate a committed page
                                 PAGE_READWRITE);    // read/write access

ну никак не заработает?

The VirtualAlloc function reserves or commits a region of pages in the virtual address space of the calling process. Memory allocated by this function is automatically initialized to zero, unless MEM_RESET is specified.

The GlobalAlloc function allocates the specified number of bytes from the heap. Windows memory management does not provide a separate local heap and global heap.

Note  The global 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, the clipboard functions, and OLE data objects.


 
Vovan #2   (2007-01-04 23:56) [10]

Буферы нужны для аудиоустройства.

>У GlobalAlloc своя специфика.

Специфика в чём?

В Интернете я нашёл лишь одно отличие GlobalAlloc от GetMem:

"Диспетчер памяти заточен под приложения, выделяющие большое количество небольших объёмов памяти, что является характерным для ООП-приложений и приложений, обрабатывающих строковые данные. Другие менеджеры памяти (такие, как реализации GlobalAlloc, LocalAlloc, а также виндовая поддержка куч (heap)) не являются оптимальными в подобных ситуациях и могут замедлить приложение."

Т.е. различие в количестве памяти, при котором работа эффективна.

Я так понял, что если мне приспичит, то я могу сколько угодно памяти взять и тупо выделить через GetMem, и плевать как медленно всё будет работать, главное, что всё будет работать правильно, так?


 
Vovan #2   (2007-01-05 16:25) [11]

Только что читаю и понимаю, что прямо про мой случай:

All non-trivial abstractions, to some degree, are leaky.

http://www.joelonsoftware.com/articles/LeakyAbstractions.html

GetMem GetMem"ом, но рано или поздно...


 
С   (2007-01-05 17:01) [12]

MetalFan ©   (04.01.07 23:47) [9]

А Вы поинтересуйтесь, сколько на самом деле будет выделено. Например, с помощью VirtualQuery или просто попробуйте записать по полученному адресу число типа INTEGER. Боюсь, Вас ждет сюрприз:)

>почитайте же наконец спец.литературу или на худой конец MSDN!!!

Хороший совет, последуйте ему:))


 
GrayFace ©   (2007-01-10 17:34) [13]

MetalFan ©   (04.01.07 23:47) [9]
> VirtualAlloc выделяет только большие блоки памяти
да ну что вы говорите?!

dwSize
[in] Size of the region, in bytes. If the lpAddress parameter is NULL, this value is rounded up to the next page boundary. Otherwise, the allocated pages include all pages containing one or more bytes in the range from lpAddress to (lpAddress+dwSize). This means that a 2-byte range straddling a page boundary causes both pages to be included in the allocated region.

Vovan #2   (04.01.07 23:56) [10]
Я так понял, что если мне приспичит, то я могу сколько угодно памяти взять и тупо выделить через GetMem, и плевать как медленно всё будет работать, главное, что всё будет работать правильно, так?

Вряд ли можно скажать, что это будет работать ощутимо медленнее. Просто, если у тебя есть какой-то код, выделяющий память блоками и размер блоков равный размеру страницы подходит для задачи, то логично использовать VirtualAlloc. А так, менеджер памяти нормально работает и с большими блоками, но наверняка сохраняет кое-какую информацию о выделенном блоке. Еще блок, выделенный менеджером памяти может быть уничтожен только им, поэтому для передачи строк между exe и dll приходится использовать ShareMem (или заботиться о том, чтобы строки уничтожалсь тем менеджером памяти, которым они выделены).

Vovan #2   (04.01.07 23:56) [10]
Специфика в чём?


В However, the global functions are still used with DDE, the clipboard functions, and OLE data objects.


 
GrayFace ©   (2007-01-10 17:43) [14]

Еще VirtualAlloc поддерживает выделение памяти по конкретному адресу, MEM_RESERVE и пр. - см. MSDN.


 
Сергей М. ©   (2007-01-10 17:51) [15]


> Vovan #2   (04.01.07 19:29)


> чем отличаются GlobalAlloc от VirtualAlloc


GlobalAlloc - более высокоуровневая ф-ция аллокации ресурсов памяти, чем VirtualAlloc, она несет более высокую смысловую и функциональную нагрузку.

Не вдаваясь в подробности (кроме тех, что GlobalAlloc в ходе своего выполнения при определенных условиях вызывает ту же VirtualAlloc) с учетом

> Буферы нужны для аудиоустройства

рекомендация такова: пользуй GlobalAlloc() с флагом GMEM_FIXED - в большинстве случаев это как раз то что нужно для резерверования буферов, с которыми работают драйверы устройств высокоскоростного ввода/вывода


 
Сергей М. ©   (2007-01-10 18:02) [16]


> Что за штука такая PChar, что люди объявляют Buf: array
> of PChar, а потом делают buf := VirtualAlloc(параметры)?
> ??


Сомневаюсь, что люди делают именно так.

Скорее всего люди делают так:
type
 TPCharArray = array[границы диапазона индексов] of PChar;

var
 Buf: TPCharArray;

..

Buf := VirtualAlloc(..);

PChar - это просто некий указательный тип, используемый для информирования компилятора о том, что под данными такого типа подразумеваются указатели однобайтный символ или на цепочки однобайтных символов. Т.е. данные такого типа компилятор будет рассматривать как типизированные указатели, по аналогии с PByte (указатель на байт), PWord (указатель на слово), PInteger (указатель на данные типа интеджер) и т.п.


 
DevilDevil ©   (2007-01-10 18:16) [17]

Раз уж тема о выделении памяти зашла, позвольте поинтересовтаься, давно вот интересует: возможно ли указать Delphi чтобы выделяла память по опрелелённой границе в 4, 8 или 16 байт?


 
ors_archangel ©   (2007-01-10 18:51) [18]


> DevilDevil ©   (10.01.07 18:16) [17]
> Раз уж тема о выделении памяти зашла, позвольте поинтересовтаься,
>  давно вот интересует: возможно ли указать Delphi чтобы
> выделяла память по опрелелённой границе в 4, 8 или 16 байт?

Стандартный менеджер всегда обеспечивает 4б выравнивание:

---getmem.inc---
const
 cAlign        = 4;
-----------------

Но cAlign - это константа


 
ors_archangel ©   (2007-01-10 18:53) [19]


> GrayFace ©   (10.01.07 17:43) [14]
> Еще VirtualAlloc поддерживает выделение памяти по конкретному
> адресу, MEM_RESERVE и пр. - см. MSDN.

Ещё VirtualAlloc позволяет "выделять" страницы COPY_ON_WRITE, так можно делать lazzy allocation, в принципе, или бесплатно раскопировать одну страницу на большую область ВАП, если они будут read-only, тут мешает только гранулярность - 4/8 kb


 
tesseract ©   (2007-01-11 00:13) [20]


> ors_archangel ©   (10.01.07 18:51) [18]
> Но cAlign - это константа


Для записей не совсем так, можно задать выравнивание самому, или просто использовать packed.



Страницы: 1 вся ветка

Форум: "Начинающим";
Текущий архив: 2007.01.28;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.51 MB
Время: 0.048 c
15-1168599776
Rouse_
2007-01-12 14:02
2007.01.28
Как правильно рисовать в MS Paint - е :)


15-1168006020
IMHO
2007-01-05 17:07
2007.01.28
Вечная компьютерная игра


15-1168244906
Nic
2007-01-08 11:28
2007.01.28
Регистрация Turbo Delphi :)


1-1165419214
MJShvedov
2006-12-06 18:33
2007.01.28
Как можно определить параметр ячейки DrawGrid?


3-1163062331
novill
2006-11-09 11:52
2007.01.28
IB 7.5 Как в триггере изнать сколько записей вернул подзапрос?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский