OberonCore
https://forum.oberoncore.ru/

Ограничение на размер кучи в XDS
https://forum.oberoncore.ru/viewtopic.php?f=30&t=3533
Страница 1 из 1

Автор:  GameHunter [ Пятница, 12 Август, 2011 13:52 ]
Заголовок сообщения:  Ограничение на размер кучи в XDS

XDS (Оберон) не может выделить больше гигобайта памяти в куче, сколь я ни игрался с уравнением HEAPLIMIT. Никто не встречался с таким ограничением? Delphi 7 у меня выделяет вплоть до 2 Гб, как и положено.

Автор:  Александр Ильин [ Пятница, 12 Август, 2011 17:20 ]
Заголовок сообщения:  Re: Ограничение на размер кучи в XDS

Аналогично. Больше всего кучи можно выделить, если задать HeapLimit = 0, но это всё равно будет немногим больше гигабайта.

Автор:  Александр Ильин [ Пятница, 12 Август, 2011 17:59 ]
Заголовок сообщения:  Re: Ограничение на размер кучи в XDS

Вот тестовая программка, см. комментарии к процедурам.
Код:
<*+main*> (* This marks the main module of a program or library.            *)
<*heaplimit="0"*> (* Automatic heap size. Set other values to see effect.   *)

MODULE Test;

(* ------------------------------------------------------------------------
 * (C) 2011 by Alexander Iljin
 * ------------------------------------------------------------------------ *)

IMPORT oberonRTS, Out;

TYPE
   Chain = POINTER TO ChainDesc;
   ChainDesc = RECORD
      (* data size is 1 MByte minus pointer variable size *)
      data: ARRAY 1024 * 1024 DIV SIZE (LONGINT) - 1 OF LONGINT;
      next: Chain;
   END;

PROCEDURE CheckMaxHeapSize ();
(* Output the number of megabytes that were successfully allocated in heap.
 * The whole chain of allocated blocks stays rooted in the 'root' variable.
 * This test shows that it's impossible to allocate more than 1 Gb of heap
 * in XDS v2.51. The number goes up to 1066 Mb, while the expected limit would
 * be around 2 Gb on 32-bit systems. *)
VAR
   root, new: Chain;
   i: INTEGER;
BEGIN
   root := NIL;
   new := NIL;
   NEW (root);
   root.next := NIL;
   i := 1;
   Out.Int (i, 0);
   Out.Char (' ');
   LOOP
      NEW (new);
      new.next := root;
      root := new;
      INC (i);
      Out.Int (i, 0);
      Out.Char (' ');
   END;
END CheckMaxHeapSize;

PROCEDURE CheckCollector ();
(* The newly allocated blocks are not rooted in any global variable. The local
 * variable 'root' references only one block at a time, and oberonRTS.Collect
 * is called after every allocation, but still the heap is exhausted very
 * quickly (the numbers go to 1205 instead of 1066). This demonstrates a bug
 * in XDS memory management. *)
VAR
   root: Chain;
   i: INTEGER;
BEGIN
   root := NIL;
   NEW (root);
   root.next := NIL;
   i := 1;
   Out.Int (i, 0);
   Out.Char (' ');
   LOOP
      NEW (root.next);
      root := root.next; (* Note: the previous value of 'root' is lost, therefore can be garbage-collected. *)
      INC (i);
      Out.Int (i, 0);
      Out.Char (' ');
      oberonRTS.Collect;
   END;
END CheckCollector;

BEGIN
   ASSERT (SIZE (ChainDesc) = 1024*1024, 20);
   Out.Open;
   CheckMaxHeapSize;
   CheckCollector;
END Test.

Автор:  Александр Ильин [ Пятница, 30 Декабрь, 2011 16:45 ]
Заголовок сообщения:  Re: Ограничение на размер кучи в XDS

Воспроизводится без изменений в XDS 2.60 beta. Особенно огорчает проблема, демонстрируемая процедурой CheckCollector: неиспользуемая память не освобождается вовремя. В идеале процедура вообще никогда не должна завершиться, а размер выделенной памяти не должен превышать 2 Мб (размер двух экземпляров типа Chain^). Ведь там выделяется память под новый объект, ссылка на старый тут же теряется, после чего вызывается сборка мусора, и так по кругу, т.е. в памяти в каждый момент времени находится только один либо два объекта.

Автор:  Александр Ильин [ Пятница, 30 Декабрь, 2011 16:53 ]
Заголовок сообщения:  Re: Ограничение на размер кучи в XDS

Я БЫЛ НЕ ПРАВ! Сборщик мусора работает нормально, цикл в CheckCollector не завершается, и потребление памяти не растёт в том случае, если убрать модуль Out. Это он, оказывается, чем-то замусоривает память так, что её потом не удаётся выделить под основную задачу цикла.

Таким образом, претензия к неосвобождению памяти снимается (вместо неё появляется закономерный вопрос к стандартному модулю Out).

Однако, выделить больше 1 Гб по-прежнему не получается, эта проблема остаётся.

Автор:  Сергей Губанов [ Воскресенье, 01 Январь, 2012 19:05 ]
Заголовок сообщения:  Re: Ограничение на размер кучи в XDS

Александр Ильин писал(а):
вопрос к стандартному модулю Out
Уж не в консоль ли он пишет?

Были на работе случаи. Прибегают, спрашивают - ваша программа отожрала два гигабайта. Дежурный ответ - отключите вывод логов в консоль.

Автор:  Александр Ильин [ Воскресенье, 01 Январь, 2012 21:25 ]
Заголовок сообщения:  Re: Ограничение на размер кучи в XDS

Сергей Губанов писал(а):
Александр Ильин писал(а):
вопрос к стандартному модулю Out
Уж не в консоль ли он пишет?Были на работе случаи. Прибегают, спрашивают - ваша программа отожрала два гигабайта. Дежурный ответ - отключите вывод логов в консоль.
В консоль, да!
Так вот оно в чём дело! : )

Автор:  igor [ Понедельник, 02 Январь, 2012 09:50 ]
Заголовок сообщения:  Re: Ограничение на размер кучи в XDS

Извините, не понял :? . Почему тот факт, что вывод на консоль отжирает у памяти два гигабайта, считается нормальным? Или это из-за того, что стандартный модуль Out какой-то дефективный?

Автор:  Сергей Губанов [ Понедельник, 02 Январь, 2012 16:33 ]
Заголовок сообщения:  Re: Ограничение на размер кучи в XDS

igor писал(а):
модуль Out какой-то дефективный?
Не модуль, а сама системная консоль. Это не зависит от языка программирования, а зависит от нижележащей операционной системы. Консоль помнит всё, что в неё написали, вот память и растёт. Наверное есть какие-то системные средства чтобы её очищать, но их же надо явно вызывать.

Автор:  igor [ Вторник, 03 Январь, 2012 08:11 ]
Заголовок сообщения:  Re: Ограничение на размер кучи в XDS

Сергей Губанов писал(а):
Консоль помнит всё, что в неё написали, вот память и растёт.
Спасибо за разъяснения.

Сергей Губанов писал(а):
Наверное есть какие-то системные средства чтобы её очищать, но их же надо явно вызывать.
Интересно, а команда CLS в самой консоли не приводит к освобождению памяти?

Автор:  Иван Денисов [ Суббота, 11 Май, 2013 20:50 ]
Заголовок сообщения:  Re: Ограничение на размер кучи в XDS

Не могу понять в чем дело.

Вот небольшой модуль сделать решил для проверки оптимизации скорости в компиляторе XDS:
Код:
<*+main*> (* This marks the main module of a program or library.            *)
<*heaplimit="0"*> (* Automatic heap size. Set other values to see effect.   *)

MODULE Test;

   IMPORT Out;
   
   VAR
      f: ARRAY 1000 OF ARRAY 100 OF REAL;
      
   PROCEDURE Do*;
   VAR
      i, j: INTEGER; sum: REAL;
   BEGIN
      FOR i := 0 TO LEN(f, 0) - 1 DO
         FOR j := 0 TO LEN(f, 1) - 1 DO
            f[i, j] := i * j / 100000
         END
      END;
      sum := 0;
      FOR i := 0 TO LEN(f) - 1 DO
         FOR j := 0 TO LEN(f, 1) - 1 DO
            sum := sum + f[i, j]
         END
      END;
      Out.Real(sum, 5); Out.Ln      
   END Do;

BEGIN
   Do
END Test.

Но если массив хотя-бы 1000 на 100, выдает ошибку
Код:
#RTS: unhandled exception #5: whole overflow

File errinfo.$$$ created.

  EAX = 00020530  EBX = 7B8B0063
  ECX = 0000014B  EDX = 7B8B8001
  ESI = 7FFDF000  EDI = 0040C410
  EBP = 0032FE78  ESP = 0032FE1C
  EIP = 0040101F
 STACK:
  0032FE1C:  00007EB6 0040E020 7B8B3FF4 004010D5
  0032FE2C:  0040E020 0032FE48 001434F0 00000001
  0032FE3C:  001E8480 00000000 0040BBDE 00000001
  0032FE4C:  001434F0 00144B20 00000001 001434F0
  0032FE5C:  0032FEF0 0040C441 7B85F20C 7FFDF000
  0032FE6C:  7BC5036A 7B8B3FF4 7FFDF000 0032FEB8
  0032FE7C:  7B86048B 7FFDF000 0040C410 00000000
  0032FE8C:  00000000 00000000 00000000 00000000


Нужно какие-то опции компилятора менять? Помогите, пожалуйста.

Автор:  Valery Solovey [ Суббота, 11 Май, 2013 23:57 ]
Заголовок сообщения:  Re: Ограничение на размер кучи в XDS

Этот массив на стеке.

Автор:  Alexey Veselovsky [ Воскресенье, 12 Май, 2013 00:12 ]
Заголовок сообщения:  Re: Ограничение на размер кучи в XDS

Valery Solovey писал(а):
Этот массив на стеке.

Конечно же это не так. Он в "статической" памяти. Это не куча и не стек.

Автор:  Александр Ильин [ Воскресенье, 12 Май, 2013 00:36 ]
Заголовок сообщения:  Re: Ограничение на размер кучи в XDS

Иван Денисов писал(а):
Не могу понять в чем дело.
Переполнение целого числа. Вы когда 100 на 1000 умножаете, никак не укладываетесь в максимум для типа INTEGER, который равен 32767. Смотрите следующую строку:
Код:
f[i, j] := i * j / 100000
Вариант решения - посчитать в типе LONGINT:
Код:
f[i, j] := LONG(i) * j / 100000

Автор:  Иван Денисов [ Воскресенье, 12 Май, 2013 06:30 ]
Заголовок сообщения:  Re: Ограничение на размер кучи в XDS

Алексей, спасибо за объяснение про тип памяти.
Александр, огромное спасибо за целые. Теперь все работает!

Прошу прощения, за оффтоп, думал, это как-то связанно с кучей. Евгений, порошу начиная с моего сообщения выше перенести в отдельную тему, например, «Ограничение размера INTEGER при вычислениях».

Страница 1 из 1 Часовой пояс: UTC + 3 часа
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/