Автор Тема: Как обходиться без сборщика мусора?  (Прочитано 14714 раз)

Valery Solovey

  • Hero Member
  • *****
  • Сообщений: 509
    • Просмотр профиля
Как обходиться без сборщика мусора?
« : Февраль 07, 2012, 07:45:01 pm »
Не лучше ли прививать культуру работы с памятью. Нет же в этом ничего заумного и трудного. Меня не напрягает для программ, где используется много объектов, расписывать карту памяти... это позволяет заблаговременно понять, что же и как, собственно, делается в программе... увидеть узкие места.
В частности, что конкретно подразумевается под картами памяти и как их составлять?

vlad

  • Hero Member
  • *****
  • Сообщений: 1391
    • Просмотр профиля
Re: Как обходиться без сборщика мусора?
« Ответ #1 : Февраль 07, 2012, 08:16:44 pm »
Не лучше ли прививать культуру работы с памятью. Нет же в этом ничего заумного и трудного. Меня не напрягает для программ, где используется много объектов, расписывать карту памяти... это позволяет заблаговременно понять, что же и как, собственно, делается в программе... увидеть узкие места.
В частности, что конкретно подразумевается под картами памяти и как их составлять?

Да-да! И про конкатенацию строк тоже напишите пожалуйста! :)

Valery Solovey

  • Hero Member
  • *****
  • Сообщений: 509
    • Просмотр профиля
Re: Как обходиться без сборщика мусора?
« Ответ #2 : Февраль 11, 2012, 05:16:04 pm »
Конкатенация, ладно. А как с памятью лучше управляться самому? С тактической и стратегической точек зрения. Какие используете методы?

Ну и собственно про карты хотелось бы услышать. Пользуется кто, кроме alexus-а?

Губанов Сергей Юрьевич

  • Hero Member
  • *****
  • Сообщений: 590
    • Просмотр профиля
    • Домашняя страница
Re: Как обходиться без сборщика мусора?
« Ответ #3 : Февраль 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).



alexus

  • Гость
Re: Как обходиться без сборщика мусора?
« Ответ #4 : Февраль 11, 2012, 08:06:05 pm »
Не лучше ли прививать культуру работы с памятью. Нет же в этом ничего заумного и трудного. Меня не напрягает для программ, где используется много объектов, расписывать карту памяти... это позволяет заблаговременно понять, что же и как, собственно, делается в программе... увидеть узкие места.
В частности, что конкретно подразумевается под картами памяти и как их составлять?
Это довольно просто. Пусть для работы программы необходима динамически выделяемая память. Распределение памяти под динамические структуры представляется в виде карты памяти программы.
Предположим, что мы пишем программу по работе с заказами. Для комфортной работы пользователей желательно, чтобы необходимая им информация находилась "на кончиках пальцев", дабы её получения не пришлось ожидать долго. Какая информация может понадобиться пользователям при работе с заказами?
  • о принятых заказах;
  • о поступивших заявках;
  • о продукции и услугах;
  • о ценах (прейскуранты);
  • о платежах;
  • об отгрузках;
  • о складских запасах;
  • о заказчиках;
Информация хранится в реляционной БД, то есть, является структурированной.
При старте приложения необходимая для работы информация закачивается в приложение и располагается в памяти в виде массивов структур соответствующих типов.
Карта памяти отражает сколько памяти выделяется под каждый массив структур, какие массивы структур перечитываются из БД и при каких событиях/действиях пользователя.
Конечно, не вся информация закачивается в приложение сразу. Например, чтобы увидеть параметры продукции/услуг пользователь вызовет нужную форму, и при старте данной формы требуемая информация будет получена из БД. Но при проектировании приложения проектировщик должен гарантировать, что памяти хватит для размещения нужной информации и, если необходимо, укажет ограничения, на количество элементов того или иного вида, которые будут закачиваться из БД.
Чтобы информация не только гарантированно размещалась в памяти, но и работа с ней происходила быстро и удобно, был написан свой менеджер памяти. Суть его работы проста...
При инициализации указывается совокупный размер пула (необходимый размер памяти). При этом физическая память не выделяется. При закачке данных запрашивается нужный под данную структуру размер памяти и она выделяется/закрепляется, и её адрес возвращается запрашивающей программе. Как следствие, закачиваемые структуры располагаются последовательно, как элементы массива. Освобождение памяти может происходить полностью или частями.
Вот, собственно, и всё.

Губанов Сергей Юрьевич

  • Hero Member
  • *****
  • Сообщений: 590
    • Просмотр профиля
    • Домашняя страница
Re: Как обходиться без сборщика мусора?
« Ответ #5 : Февраль 13, 2012, 08:44:50 pm »
Много объектов в моей программе может быть размещено в массивах структур. Много, но не все. Как быть с полиморфными объектами? Для вызова виртуальной функции нужен настоящий (трассируемый сборщиком мусора) указатель на объект, а не индекс массива...

alexus

  • Гость
Re: Как обходиться без сборщика мусора?
« Ответ #6 : Февраль 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;
В моих задачах выделение памяти происходит быстро (освобождение, тем более) и этим удобно пользоваться. Но для других задач возможно такой простой менеджер памяти не подойдёт.

Губанов Сергей Юрьевич

  • Hero Member
  • *****
  • Сообщений: 590
    • Просмотр профиля
    • Домашняя страница
Re: Как обходиться без сборщика мусора?
« Ответ #7 : Февраль 13, 2012, 09:46:47 pm »
У меня это реализовано так:
У Вас хотя и с указателями, но тоже без полиморфных объектов (по таким unsafe указателям виртуальную функцию не вызовешь).

Вот ведь засада! То есть если мне нужно миллион полиморфных объектов, то от сборщика мусора их в массивы структур не спрячешь  >:(

alexus

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

Вот ведь засада! То есть если мне нужно миллион полиморфных объектов, то от сборщика мусора их в массивы структур не спрячешь  >:(
У меня есть предубеждение... против сложности, будь то сложность структур/связей или алгоритмов. Цикл Дейкстры плох тем, что он сложен, но и сложно организованные данные - это повод ещё раз "растечься мозгами по древу"... IMHO, разумеется.

Geniepro

  • Hero Member
  • *****
  • Сообщений: 1955
  • Знайте- истина в том, что повторено трижды подряд!
    • Просмотр профиля
Re: Как обходиться без сборщика мусора?
« Ответ #9 : Февраль 14, 2012, 05:06:19 am »
У меня есть предубеждение... против сложности, будь то сложность структур/связей или алгоритмов. Цикл Дейкстры плох тем, что он сложен, но и сложно организованные данные - это повод ещё раз "растечься мозгами по древу"... IMHO, разумеется.
Никак не могу понять, в чём же сложность цикла Дейкстры?
to iterate is human, to recurse, divine

Салат «рекурсия»: помидоры, огурцы, салат…

alexus

  • Гость
Re: Как обходиться без сборщика мусора?
« Ответ #10 : Февраль 14, 2012, 05:25:54 am »
У меня есть предубеждение... против сложности, будь то сложность структур/связей или алгоритмов. Цикл Дейкстры плох тем, что он сложен, но и сложно организованные данные - это повод ещё раз "растечься мозгами по древу"... IMHO, разумеется.
Никак не могу понять, в чём же сложность цикла Дейкстры?
В том, что используются совершенно разные "охраняющие условия"... то есть, различные логические конструкции объединятся в одну только на том основании, что они выполнятся циклически. Разобраться и понять эту объединённую логику не всегда легко. Даже конечные автоматы с учётом множества состояний проще и понятнее писать без использования ЦД.

Geniepro

  • Hero Member
  • *****
  • Сообщений: 1955
  • Знайте- истина в том, что повторено трижды подряд!
    • Просмотр профиля
Re: Как обходиться без сборщика мусора?
« Ответ #11 : Февраль 14, 2012, 11:18:46 am »
Никак не могу понять, в чём же сложность цикла Дейкстры?
В том, что используются совершенно разные "охраняющие условия"... то есть, различные логические конструкции объединятся в одну только на том основании, что они выполнятся циклически. Разобраться и понять эту объединённую логику не всегда легко. Даже конечные автоматы с учётом множества состояний проще и понятнее писать без использования ЦД.

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

Вот, например, хаскелл -- там нет циклов вообще и их имитировать приходится с помощью рекурсии.
В результате часто получаются вполне нормальные функции, которые фактически являются реализацией цикла Дейкстры (с некоторым синтаксическим оверхедом на рекурсивный вызов).
Никаких проблем с такими логическими конструкциями нет совершенно, и, думаю, это благодаря более удобному синтаксическому оформлению кода (даже несмотря на тот оверхед)...
to iterate is human, to recurse, divine

Салат «рекурсия»: помидоры, огурцы, салат…

valexey

  • Administrator
  • Hero Member
  • *****
  • Сообщений: 1990
    • Просмотр профиля
Re: Как обходиться без сборщика мусора?
« Ответ #12 : Февраль 14, 2012, 12:28:11 pm »
Возможно, это проблема неудобного синтаксиса.

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

Valery Solovey

  • Hero Member
  • *****
  • Сообщений: 509
    • Просмотр профиля
Re: Как обходиться без сборщика мусора?
« Ответ #13 : Февраль 14, 2012, 12:51:19 pm »
Распределение памяти под динамические структуры представляется в виде карты памяти программы. [...]
Я пока не в состоянии полностью понять, о чём речь. Карта памяти - это инструмент проектирования или какое-то свойство программы? Вы в соседней ветке говорили что-то вроде того, что карту памяти стоит для начала на бумаге изобразить для пущей пользы.
« Последнее редактирование: Февраль 14, 2012, 12:55:49 pm от Valery Solovey »

alexus

  • Гость
Re: Как обходиться без сборщика мусора?
« Ответ #14 : Февраль 14, 2012, 02:53:04 pm »
Распределение памяти под динамические структуры представляется в виде карты памяти программы. [...]
Я пока не в состоянии полностью понять, о чём речь. Карта памяти - это инструмент проектирования или какое-то свойство программы? Вы в соседней ветке говорили что-то вроде того, что карту памяти стоит для начала на бумаге изобразить для пущей пользы.
Карта памяти позволяет при проектировании понять, сколько и под какие массивы структур отводится памяти, соответственно, продумать систему ограничений. Например, не нужно каждый раз загружать все заказы, рано или поздно, их станет слишком/избыточно много. Поэтому "по умолчанию" загружаются только незакрытые заказы за определённый период времени. Какой период времени выбрать? Предположим, что в среднем в день обрабатывается 150-200 заказов. Значит за 3 месяца принимается 3 * 24 * 200 заказов. Умножаем на размер структуры заказа, умножаем на "коэффициент запаса прочности ~7-10) и получаем примерный размер памяти выделяемый под заказы. Заказчик машет рукой... "Нет 3 месяца это мало, у меня порой висят заказы за полгода!" или наоборот: "Нет три месяца - это много, мы через месяц все неоплаченные заказы анулируем!". Хорошо домножаем на два в первом случае, делим на три во втором... и смотрим... хватает ли нам памяти для размещения всех остальных данных... Это простой инженерный подход. Точно также конструктор должен подтвердить расчётом, каждый болт (на срез, кручение, изгиб...), каждую заклёпку... Ничего хитрого, как видите.