Oberon space

General Category => Общий раздел => Тема начата: Valery Solovey от Февраль 07, 2012, 07:45:01 pm

Название: Как обходиться без сборщика мусора?
Отправлено: Valery Solovey от Февраль 07, 2012, 07:45:01 pm
Не лучше ли прививать культуру работы с памятью. Нет же в этом ничего заумного и трудного. Меня не напрягает для программ, где используется много объектов, расписывать карту памяти... это позволяет заблаговременно понять, что же и как, собственно, делается в программе... увидеть узкие места.
В частности, что конкретно подразумевается под картами памяти и как их составлять?
Название: Re: Как обходиться без сборщика мусора?
Отправлено: vlad от Февраль 07, 2012, 08:16:44 pm
Не лучше ли прививать культуру работы с памятью. Нет же в этом ничего заумного и трудного. Меня не напрягает для программ, где используется много объектов, расписывать карту памяти... это позволяет заблаговременно понять, что же и как, собственно, делается в программе... увидеть узкие места.
В частности, что конкретно подразумевается под картами памяти и как их составлять?

Да-да! И про конкатенацию строк тоже напишите пожалуйста! :)
Название: Re: Как обходиться без сборщика мусора?
Отправлено: Valery Solovey от Февраль 11, 2012, 05:16:04 pm
Конкатенация, ладно. А как с памятью лучше управляться самому? С тактической и стратегической точек зрения. Какие используете методы?

Ну и собственно про карты хотелось бы услышать. Пользуется кто, кроме alexus-а?
Название: Re: Как обходиться без сборщика мусора?
Отправлено: Губанов Сергей Юрьевич от Февраль 11, 2012, 07:11:30 pm
На работе на этой неделе применил способ размещения объектов в массивах структур. Чтобы при увеличении количества объектов не реаллоцировать массив с целью увеличения сделал его двумерным и адресуюсь по сегменту-смещению. По мере надобности добавляю новый сегмент.

В качестве "указателя" на объект выступает 4-байтовая структура на вроде такой:

public struct PointerToMyObject
{
    private ushort segment, offset;

    public int SomeValue1
    {
      get
      {
        return descriptors[this.segment][this.offset].someValue1;
      }
    }

    public void DoSomething1 (int x, int y)
    {
      descriptors[this.segment][this.offset].DoSomething1(x, y);
    }
}

descriptors -- двумерный массив структур (тушки объектов MyObject).


Название: Re: Как обходиться без сборщика мусора?
Отправлено: alexus от Февраль 11, 2012, 08:06:05 pm
Не лучше ли прививать культуру работы с памятью. Нет же в этом ничего заумного и трудного. Меня не напрягает для программ, где используется много объектов, расписывать карту памяти... это позволяет заблаговременно понять, что же и как, собственно, делается в программе... увидеть узкие места.
В частности, что конкретно подразумевается под картами памяти и как их составлять?
Это довольно просто. Пусть для работы программы необходима динамически выделяемая память. Распределение памяти под динамические структуры представляется в виде карты памяти программы.
Предположим, что мы пишем программу по работе с заказами. Для комфортной работы пользователей желательно, чтобы необходимая им информация находилась "на кончиках пальцев", дабы её получения не пришлось ожидать долго. Какая информация может понадобиться пользователям при работе с заказами?
Информация хранится в реляционной БД, то есть, является структурированной.
При старте приложения необходимая для работы информация закачивается в приложение и располагается в памяти в виде массивов структур соответствующих типов.
Карта памяти отражает сколько памяти выделяется под каждый массив структур, какие массивы структур перечитываются из БД и при каких событиях/действиях пользователя.
Конечно, не вся информация закачивается в приложение сразу. Например, чтобы увидеть параметры продукции/услуг пользователь вызовет нужную форму, и при старте данной формы требуемая информация будет получена из БД. Но при проектировании приложения проектировщик должен гарантировать, что памяти хватит для размещения нужной информации и, если необходимо, укажет ограничения, на количество элементов того или иного вида, которые будут закачиваться из БД.
Чтобы информация не только гарантированно размещалась в памяти, но и работа с ней происходила быстро и удобно, был написан свой менеджер памяти. Суть его работы проста...
При инициализации указывается совокупный размер пула (необходимый размер памяти). При этом физическая память не выделяется. При закачке данных запрашивается нужный под данную структуру размер памяти и она выделяется/закрепляется, и её адрес возвращается запрашивающей программе. Как следствие, закачиваемые структуры располагаются последовательно, как элементы массива. Освобождение памяти может происходить полностью или частями.
Вот, собственно, и всё.
Название: Re: Как обходиться без сборщика мусора?
Отправлено: Губанов Сергей Юрьевич от Февраль 13, 2012, 08:44:50 pm
Много объектов в моей программе может быть размещено в массивах структур. Много, но не все. Как быть с полиморфными объектами? Для вызова виртуальной функции нужен настоящий (трассируемый сборщиком мусора) указатель на объект, а не индекс массива...
Название: Re: Как обходиться без сборщика мусора?
Отправлено: alexus от Февраль 13, 2012, 09:04:46 pm
Много объектов в моей программе может быть размещено в массивах структур. Много, но не все. Как быть с полиморфными объектами? Для вызова виртуальной функции нужен настоящий (трассируемый сборщиком мусора) указатель на объект, а не индекс массива...
У меня это реализовано так:
// для отдельной структуры
pStruct := pool.GetSlice(SizeOf(MyStruct));

// для массива структур
cntItems := 0;
paStruct := pool.CurrentPoint;                          // получаем текущий адрес (paStruct - указатель на массив структур)
while (not query.EoF) do begin
        pool.GetSlice(SizeOf(MyStruct));                // выделяем память
        paStruct^[cntItems].Fieild_1 := query.Fields[0].AsString;  // заполняем поля структуры
        paStruct^[cntItems].Fieild_2 := query.Fields[2].AsInteger;
        paStruct^[cntItems].Fieild_3 := query.Fields[3].AsDate;
        paStruct^[cntItems].Fieild_4 := query.Fields[4].AsCurrency;
        inc(cntItems);                                            // накручиваем счётчик элементов
        query.Next;                                               // переходим к следующей записи
end;
query.Close;
В моих задачах выделение памяти происходит быстро (освобождение, тем более) и этим удобно пользоваться. Но для других задач возможно такой простой менеджер памяти не подойдёт.
Название: Re: Как обходиться без сборщика мусора?
Отправлено: Губанов Сергей Юрьевич от Февраль 13, 2012, 09:46:47 pm
У меня это реализовано так:
У Вас хотя и с указателями, но тоже без полиморфных объектов (по таким unsafe указателям виртуальную функцию не вызовешь).

Вот ведь засада! То есть если мне нужно миллион полиморфных объектов, то от сборщика мусора их в массивы структур не спрячешь  >:(
Название: Re: Как обходиться без сборщика мусора?
Отправлено: alexus от Февраль 14, 2012, 03:42:05 am
У меня это реализовано так:
У Вас хотя и с указателями, но тоже без полиморфных объектов (по таким unsafe указателям виртуальную функцию не вызовешь).

Вот ведь засада! То есть если мне нужно миллион полиморфных объектов, то от сборщика мусора их в массивы структур не спрячешь  >:(
У меня есть предубеждение... против сложности, будь то сложность структур/связей или алгоритмов. Цикл Дейкстры плох тем, что он сложен, но и сложно организованные данные - это повод ещё раз "растечься мозгами по древу"... IMHO, разумеется.
Название: Re: Как обходиться без сборщика мусора?
Отправлено: Geniepro от Февраль 14, 2012, 05:06:19 am
У меня есть предубеждение... против сложности, будь то сложность структур/связей или алгоритмов. Цикл Дейкстры плох тем, что он сложен, но и сложно организованные данные - это повод ещё раз "растечься мозгами по древу"... IMHO, разумеется.
Никак не могу понять, в чём же сложность цикла Дейкстры?
Название: Re: Как обходиться без сборщика мусора?
Отправлено: alexus от Февраль 14, 2012, 05:25:54 am
У меня есть предубеждение... против сложности, будь то сложность структур/связей или алгоритмов. Цикл Дейкстры плох тем, что он сложен, но и сложно организованные данные - это повод ещё раз "растечься мозгами по древу"... IMHO, разумеется.
Никак не могу понять, в чём же сложность цикла Дейкстры?
В том, что используются совершенно разные "охраняющие условия"... то есть, различные логические конструкции объединятся в одну только на том основании, что они выполнятся циклически. Разобраться и понять эту объединённую логику не всегда легко. Даже конечные автоматы с учётом множества состояний проще и понятнее писать без использования ЦД.
Название: Re: Как обходиться без сборщика мусора?
Отправлено: Geniepro от Февраль 14, 2012, 11:18:46 am
Никак не могу понять, в чём же сложность цикла Дейкстры?
В том, что используются совершенно разные "охраняющие условия"... то есть, различные логические конструкции объединятся в одну только на том основании, что они выполнятся циклически. Разобраться и понять эту объединённую логику не всегда легко. Даже конечные автоматы с учётом множества состояний проще и понятнее писать без использования ЦД.

Возможно, это проблема неудобного синтаксиса.

Вот, например, хаскелл -- там нет циклов вообще и их имитировать приходится с помощью рекурсии.
В результате часто получаются вполне нормальные функции, которые фактически являются реализацией цикла Дейкстры (с некоторым синтаксическим оверхедом на рекурсивный вызов).
Никаких проблем с такими логическими конструкциями нет совершенно, и, думаю, это благодаря более удобному синтаксическому оформлению кода (даже несмотря на тот оверхед)...
Название: Re: Как обходиться без сборщика мусора?
Отправлено: valexey от Февраль 14, 2012, 12:28:11 pm
Возможно, это проблема неудобного синтаксиса.

Вот, например, хаскелл -- там нет циклов вообще и их имитировать приходится с помощью рекурсии.
В результате часто получаются вполне нормальные функции, которые фактически являются реализацией цикла Дейкстры (с некоторым синтаксическим оверхедом на рекурсивный вызов).
Никаких проблем с такими логическими конструкциями нет совершенно, и, думаю, это благодаря более удобному синтаксическому оформлению кода (даже несмотря на тот оверхед)...
А где ты в Хаскеле в последний раз видел не тривиальный цикл? Ну, то-есть что-то действительно интересное.
Название: Re: Как обходиться без сборщика мусора?
Отправлено: Valery Solovey от Февраль 14, 2012, 12:51:19 pm
Распределение памяти под динамические структуры представляется в виде карты памяти программы. [...]
Я пока не в состоянии полностью понять, о чём речь. Карта памяти - это инструмент проектирования или какое-то свойство программы? Вы в соседней ветке говорили что-то вроде того, что карту памяти стоит для начала на бумаге изобразить для пущей пользы.
Название: Re: Как обходиться без сборщика мусора?
Отправлено: alexus от Февраль 14, 2012, 02:53:04 pm
Распределение памяти под динамические структуры представляется в виде карты памяти программы. [...]
Я пока не в состоянии полностью понять, о чём речь. Карта памяти - это инструмент проектирования или какое-то свойство программы? Вы в соседней ветке говорили что-то вроде того, что карту памяти стоит для начала на бумаге изобразить для пущей пользы.
Карта памяти позволяет при проектировании понять, сколько и под какие массивы структур отводится памяти, соответственно, продумать систему ограничений. Например, не нужно каждый раз загружать все заказы, рано или поздно, их станет слишком/избыточно много. Поэтому "по умолчанию" загружаются только незакрытые заказы за определённый период времени. Какой период времени выбрать? Предположим, что в среднем в день обрабатывается 150-200 заказов. Значит за 3 месяца принимается 3 * 24 * 200 заказов. Умножаем на размер структуры заказа, умножаем на "коэффициент запаса прочности ~7-10) и получаем примерный размер памяти выделяемый под заказы. Заказчик машет рукой... "Нет 3 месяца это мало, у меня порой висят заказы за полгода!" или наоборот: "Нет три месяца - это много, мы через месяц все неоплаченные заказы анулируем!". Хорошо домножаем на два в первом случае, делим на три во втором... и смотрим... хватает ли нам памяти для размещения всех остальных данных... Это простой инженерный подход. Точно также конструктор должен подтвердить расчётом, каждый болт (на срез, кручение, изгиб...), каждую заклёпку... Ничего хитрого, как видите.
Название: Re: Как обходиться без сборщика мусора?
Отправлено: Vartovyj от Февраль 14, 2012, 04:45:22 pm
В обероне, имхо, без сборщика мусора не обойтись, так как сама система задумывалась как связка ОС-ЯП с интегрированным сборщиком. А, вот возможен ли какой-нибудь, скажем, полуавтоматический режим сборки мусора?
Название: Re: Как обходиться без сборщика мусора?
Отправлено: vlad от Февраль 14, 2012, 05:05:39 pm
В обероне, имхо, без сборщика мусора не обойтись, так как сама система задумывалась как связка ОС-ЯП с интегрированным сборщиком. А, вот возможен ли какой-нибудь, скажем, полуавтоматический режим сборки мусора?

Все, что "не автоматическое" низводит ЯП до уровня С :) Ну или дельфы (если речь о паскалеподобном). Так что сборка для современного ЯВУ должна быть автоматической по определению, а всякие ручки покрутить для более эффективной сборки - можно сколько угодно придумывать.
Название: Re: Как обходиться без сборщика мусора?
Отправлено: alexus от Февраль 14, 2012, 05:07:32 pm
В том, что используются совершенно разные "охраняющие условия"... то есть, различные логические конструкции объединятся в одну только на том основании, что они выполнятся циклически. Разобраться и понять эту объединённую логику не всегда легко. Даже конечные автоматы с учётом множества состояний проще и понятнее писать без использования ЦД.
Возможно, это проблема неудобного синтаксиса.
Дело не синтаксисе... На любом языке ЦД остаётся ЦД.

Вот, например, хаскелл -- там нет циклов вообще и их имитировать приходится с помощью рекурсии.
Да, это т.н. "функциональный подход"... Не думаю, что отсутствие явных циклов - это правильно. Дело в том, что на языке программирования мы фактически записываем некую модель реальности. И чем ближе/точнее модель совпадает с реальностью, тем более адекватное описание получается. А в реальности многие процессы цикличны по своей сути. Циклически сменяются времена года, например. Но сказать, что зима вызывает весну?.. Это на любителя.

В результате часто получаются вполне нормальные функции, которые фактически являются реализацией цикла Дейкстры (с некоторым синтаксическим оверхедом на рекурсивный вызов).
Дело не в оверхеде... и не в рекурсии... дело в "охраняемых условиях". Логика у них разная...

Никаких проблем с такими логическими конструкциями нет совершенно, и, думаю, это благодаря более удобному синтаксическому оформлению кода (даже несмотря на тот оверхед)...
Это не имеет отношения к сути вопроса. С циклами тоже нет проблем... и от замены цикла на рекурсию (хотя для ЦД это допущение неверно!) ничего не меняется.
Почему неверно допущение...
Возьму определение ЦД из Википедиии (http://ru.wikipedia.org/wiki/%D0%A6%D0%B8%D0%BA%D0%BB_(%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5))
do
   P1 → S1,
     
   Pn → Sn
 od
Пусть функция, где выполняется этот ЦД называется LoopD, но в общем случае S1 <> S2 <> ... <> Sn <> LoopD. То есть, прямой рекурсии мы не получаем.
Название: Re: Как обходиться без сборщика мусора?
Отправлено: valexey от Февраль 14, 2012, 05:48:46 pm
В обероне, имхо, без сборщика мусора не обойтись, так как сама система задумывалась как связка ОС-ЯП с интегрированным сборщиком.
C чего бы вдруг? Оберон отлично обходится без сборщика мусора. См например тот же Astrobe или там Pow!. Без сборщика мусора скорее Haskell не сможет обойтись.
Название: Re: Как обходиться без сборщика мусора?
Отправлено: Valery Solovey от Февраль 15, 2012, 09:42:09 am
Точно также конструктор должен подтвердить расчётом, каждый болт (на срез, кручение, изгиб...), каждую заклёпку... Ничего хитрого, как видите.
То есть, это инструмент проектирования, абстракция, представляющая собо расчёты? Никакого графического воплощения у неё нет.
Название: Re: Как обходиться без сборщика мусора?
Отправлено: alexus от Февраль 15, 2012, 10:14:46 am
Точно также конструктор должен подтвердить расчётом, каждый болт (на срез, кручение, изгиб...), каждую заклёпку... Ничего хитрого, как видите.
То есть, это инструмент проектирования, абстракция, представляющая собо расчёты? Никакого графического воплощения у неё нет.
Есть и графическое... карандашом... на бумаге... потом в каком-нибудь Draw из OpenOffice. Надо же не только для основного процесса нарисовать, но посмотреть, что получается при вызове разных справочных форм, в разных сочетаниях... А специального инструмента... нет, не делали. А зачем?.. На очередной стадии проектирования, прорисовали, приложили, сформировали константы типа MAX_N_CUSTOMERS = ...
Название: Re: Как обходиться без сборщика мусора?
Отправлено: Valery Solovey от Февраль 15, 2012, 10:39:43 am
Нет, говоря про инструмент, я не имел в виду программу. Карандаш тоже подходит : ). А как оно на бумаге появляется? В виде графов? Для чего используются узлы, для чего стрелки...

Я так понимаю, что карта описывает не только статическое состояние системы, но и переходы между ними. Так? Например, начиная с какого-то момента нам больше не нужно столько памяти вот здесь. Мы её освобождаем, и появляется достаточно памяти для данных из БД.
Название: Re: Как обходиться без сборщика мусора?
Отправлено: alexus от Февраль 15, 2012, 10:55:55 am
Нет, говоря про инструмент, я не имел в виду программу. Карандаш тоже подходит : ). А как оно на бумаге появляется? В виде графов? Для чего используются узлы, для чего стрелки...

Я так понимаю, что карта описывает не только статическое состояние системы, но и переходы между ними. Так? Например, начиная с какого-то момента нам больше не нужно столько памяти вот здесь. Мы её освобождаем, и появляется достаточно памяти для данных из БД.
Это простая матрица... Пусть в строках указываются элементы, которым нужна память (формы, пулы, например). Пусть в столбцах указываются состояния элементов... Внизу итоговая строка, максимум по которой и есть максимальный размер памяти, который требуется программе.
Название: Re: Как обходиться без сборщика мусора?
Отправлено: Geniepro от Февраль 20, 2012, 06:13:53 am
Дело не в оверхеде... и не в рекурсии... дело в "охраняемых условиях". Логика у них разная...
Просто надо использовать каждый инструмент по его назначению.
Например, сортировка 4 чисел или вычисление НОДа с помощью ЦД (классические примеры использования ЦД) -- нормально и понятно, логика каждого условия подходящая.
А вот поиск элемента в многомерном (двухмерном хотя бы) массиве с помощью ЦД выглядит неестественно, потому и кажется, что ЦД для этого не подходит...
Название: Re: Как обходиться без сборщика мусора?
Отправлено: alexus от Февраль 20, 2012, 12:59:42 pm
Дело не в оверхеде... и не в рекурсии... дело в "охраняемых условиях". Логика у них разная...
Просто надо использовать каждый инструмент по его назначению.
Золотые слова...

Например, сортировка 4 чисел или вычисление НОДа с помощью ЦД (классические примеры использования ЦД) -- нормально и понятно, логика каждого условия подходящая.
А вот поиск элемента в многомерном (двухмерном хотя бы) массиве с помощью ЦД выглядит неестественно, потому и кажется, что ЦД для этого не подходит...
Именно об этом и речь. Область применимости ЦД очень узка, и рекомендации по его "всеобщему применению" - излишне тенденциозны.