OberonCore https://forum.oberoncore.ru/ |
|
Ограничение на размер аллокированной памяти в BB? https://forum.oberoncore.ru/viewtopic.php?f=2&t=2753 |
Страница 1 из 1 |
Автор: | QWERTYProgrammer [ Понедельник, 26 Июль, 2010 23:40 ] |
Заголовок сообщения: | Ограничение на размер аллокированной памяти в BB? |
Есть ли у BB внутреннее ограничение на размер аллокированной памяти? При попытке зааллокировать максимально возможное количество памяти Код: MODULE TestAllocate; IMPORT Log := StdLog; PROCEDURE Do* (bits: INTEGER); VAR a: ARRAY 64 OF POINTER TO ARRAY OF REAL; n, i, j: INTEGER; mem, memtot: REAL; BEGIN n := ASH(1, bits); memtot := 0; j := 0; NEW(a[j], n); WHILE (j < 64) & (a[j] # NIL)DO FOR i := 0 TO n - 1 DO a[j, i] := 0 END; mem := n * SIZE(REAL) / 1024. / 1024.; memtot := mem + memtot; Log.Int(j); Log.String(":"); Log.Tab; Log.Real(mem); Log.String(" MB"); Log.Tab; Log.Real(memtot); Log.String(" MB"); Log.Ln; INC(j); IF j < 64 THEN NEW(a[j], n) END END; IF j < 64 THEN Log.String("Not enough memory"); Log.Ln END; FOR j := 0 TO 63 DO a[j] := NIL END END Do; END TestAllocate. ^Q"TestAllocate.Do(24)" BB останавливается на ~1.4-1.5 ГБ, причем как на машине с 2 ГБ памяти, так и на машине с 6 ГБ памяти. При этом на 6 ГБ машине удается запустить вторую копию BB, в которой также можно аллокировать до 1.5 ГБ, т.е. память вроде доступна ОС, но не доступна BB. |
Автор: | Илья Ермаков [ Вторник, 27 Июль, 2010 00:52 ] |
Заголовок сообщения: | Re: Ограничение на размер аллокированной памяти в BB? |
Что нужно учитывать: - в Win32 процессу доступно виртуальное адресное пространство 2Гб, не более того. Дальнейшие адреса зарезервированы для ОС (туда идёт мэппинг системных библиотек, KERNEL32, насколько помню, как раз там же и т.п., хотя для пользователя совершенно неясно, подо что так много зарезервировано). Есть у NT начиная с 2000-го ключик в boot.ini, который отдаёт процессам 3Гб адресного пространства. - если запуск идёт на Win64, то там вообще какие-то свои законы для 32-разрядной подсистемы. - некоторое количество памяти отжирают служебные структуры кучи. Но, конечно, не 0.4 Гб, тем более, что у Вас несколько крупных объектов. - эффективно распределить 0.4 Гб может оказаться невозможным из-за фрагментации. Там просто реально может не найтись непрерывного куска 130Мб, который Вы просите очередным NEW. Там ведь сидят модули, DLL-ки, наконец, сама WinApi в графическом приложении наверняка имеет выделенную память в пользовательском пространстве, в системной куче процесса (WinApi.HeapAlloc). В общих чертах так. |
Автор: | Илья Ермаков [ Вторник, 27 Июль, 2010 01:07 ] |
Заголовок сообщения: | Re: Ограничение на размер аллокированной памяти в BB? |
Вот как работает диспетчер кучи ББ (в основном режиме, там есть ещё режим для случая DLL - когда блоки запрашиваются у стандартного системного HeapAlloc). Код: PROCEDURE AllocHeapMem (size: INTEGER; VAR c: Cluster); (* allocate at least size bytes, typically at least 256 kbytes are allocated *) CONST M = 1536 * 100000H; (* 1.5 GByte *) CONST N = 65536; (* cluster size for dll *) VAR adr, s: INTEGER; ББ пытается зарезервировать под свою кучу в адресном пространстве процесса кластер размером начиная с M байт (деля M пополам, если не получилось, пока не получится). Резервируются только адреса (reserve виртуальной памяти). Таким образом, при старте ББ резервируется 1 кластер памяти 1.5 Гб, в рамках которого идёт реальное выделение блоков (commit зарезервированных адресов) и отдача их под динамические объекты. Как только этот 1.5 Гб кластер вычерпан, происходит выделение ещё одного кластера. Тем же путём 1.5Гб делится на два, пока не удастся выделить такой кусок. Т.е. следующий кластер будет 201 Мб (т.к. 406 не влезет никак) или меньше, как повезёт. Потом - 100, а у Вас размер одного массива - 134 Мб. |
Автор: | Сергей Губанов [ Вторник, 27 Июль, 2010 12:03 ] |
Заголовок сообщения: | Re: Ограничение на размер аллокированной памяти в BB? |
Ещё замечено, что под 32-битной Windows XP иногда удаётся взять у системы почти два гига, а в 32-битной Windows 7 удаётся взять то ли всего полтора, то ли 1.7, вобщем поменьше (на компе с семёркой у меня видюха интегрёная, может быть из-за этого?). |
Автор: | QWERTYProgrammer [ Среда, 28 Июль, 2010 00:11 ] |
Заголовок сообщения: | Re: Ограничение на размер аллокированной памяти в BB? |
Илья Ермаков писал(а): Как только этот 1.5 Гб кластер вычерпан, происходит выделение ещё одного кластера. Тем же путём 1.5Гб делится на два, пока не удастся выделить такой кусок. Спасибо! Посмотрев код Kernel, мне правда кажется, что в случае dllMem = FALSE, AllocHeapMem вызывается только один раз при инициализации, а наращивание памяти происходит только за счет GrowHeapMem в пределах одного кластера root. Т.е. при инициализации BB пытается зарезервировать 1.5 ГБ памяти или меньше (1.5/2, 1.5/4, ...) и дальнейшее реальное выделение блоков происходит только в пределах изначально зарезервированного пространства. И, как следствие, BB в не dll-моде в принципе не может взять у системы больше этих самых 1.5 ГБ. Может такое быть? |
Автор: | Илья Ермаков [ Среда, 28 Июль, 2010 10:15 ] |
Заголовок сообщения: | Re: Ограничение на размер аллокированной памяти в BB? |
Да, Вы действительно внимательно посмотрели. В NewBlock AllocHeapMem вызывается только в ветке dllMem, на что я вчера ночью не обратил внимания ![]() |
Автор: | QWERTYProgrammer [ Среда, 28 Июль, 2010 23:20 ] |
Заголовок сообщения: | Re: Ограничение на размер аллокированной памяти в BB? |
Что вызывает удивление, так это работа сборщика мусора. Cначала запускаю приведенную выше программу с аллокацией блоков по 128 МБ, удается зааллокировать 1.4 ГБ. ОК. Затем запускаю ту же программу с аллокацией блоков по 32 МБ (TestAllocate4.Do(22)). Удается зааллокировать 1.1 ГБ. Ладно. Теперь опять пытаюсь аллокировать блоки по 128 МБ: не удается зааллокировать ни один блок! Казалось бы, сборщик мусора должен при первом требовании освободить место в изначально выделенном адресном пространстве, поскольку на элементы массива после отработки программы ссылок уже нет? Services.Collect ситуации не меняет. Правда, если многократно запускать TestAllocate4.Do(24), то в какой-то момент удается таки зааллокировать первые 128 МБ, затем больше и в конце-концов опять дойти до 1.4 ГБ! Т.е. сборщик мусора в конце-концов таки срабатывает, правда отдает блоки памяти очень неохотно. Такое поведение это что - особенность реализации сборки мусора или все-же баг?? |
Автор: | Илья Ермаков [ Среда, 28 Июль, 2010 23:54 ] |
Заголовок сообщения: | Re: Ограничение на размер аллокированной памяти в BB? |
Ну да... Потому что фактически освободившиеся блоки не расформировываются, они висят в списке старых, для повторного использования... В случае ~dllMem, опять же. Там ряд аспектов в плане стратегии может быть модифицирован, если понимать, подо что тюнить. Хотя для динамического распределения больших линейных областей памяти как-то массивы не всегда применяют. Иногда делают что-то типа Files.File в памяти - и элементы оттуда считывают/записывают. Тогда и на диск прозрачно свопить можно. Обычная динамическая память хороша, когда много мелких объектов, ссылающихся друг на друга. Граф связей, динамика. |
Автор: | Rifat [ Четверг, 29 Июль, 2010 09:29 ] |
Заголовок сообщения: | Re: Ограничение на размер аллокированной памяти в BB? |
Проблема с тем что после выделения блоков по 32 мегабайта не удается затем выделить блоки по 128 мегабайт. Может быть из-за фрагментированности кучи. После выделения 32 мегабайт, BB может выделить сколько-нибудь памяти для своих нужд, например, если вы выводите какую-нибудь информацию в Log, затем 32 мегабайтные блоки уже не нужны, а та память которую использует BB еще нужна. Поэтому не оказывается свободных блоков по 128 мегабайт. Попробуйте посмотреть в BB Info->Heap Spy...->Show Heap. |
Автор: | Илья Ермаков [ Четверг, 29 Июль, 2010 11:05 ] |
Заголовок сообщения: | Re: Ограничение на размер аллокированной памяти в BB? |
32-мбайтные блоки висят в списке свободных блоков, а не расформировываются в просто свободное пространство. В этом и нюанс. |
Автор: | Илья Ермаков [ Суббота, 31 Июль, 2010 18:38 ] |
Заголовок сообщения: | Re: Ограничение на размер аллокированной памяти в BB? |
Угу, там слишком большой вертикальный размер вьюхи-карты, 36000 * размер_в_мм перепрыгивает за ёмкость INTEGER. Вьюхи, которые могут быть большого размера, должны делаться уже с custom-прокруткой (обрабатывать сообщение PollSectionMsg и ScrollMsg), а эта сделана "в лоб". |
Страница 1 из 1 | Часовой пояс: UTC + 3 часа |
Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |