Сборщик мусора
От: Khimik  
Дата: 05.05.19 07:50
Оценка:
Я уже писал в другой теме про свой кастомный сборщик мусора – класс TSafeObject и объект ProjectGarbageFinder в Delphi. Они выглядит примерно так:


TSafeObject=class
  public
    constructor Create;
    destructor Destroy; override;
    procedure SetThisObjectAsDebugging;//Не будет выводиться сообщение об ошибке
  end;



constructor TSafeObject.Create;
  begin
    inherited;
    if poGarbageFinderActive then begin
      ProjecTGarbageFinder.ObjectCreated(self);
    end;
  end;

destructor TSafeObject.Destroy;
  begin
    if poGarbageFinderActive then begin
      ProjecTGarbageFinder.ObjectDestroyed(self);
    end;
  inherited;
end;


Все мои классы теперь наследники TSafeObject.
Мне вначале говорили, что это не нужно, т.к. в Delphi есть опция ReportMemoryLeaksOnShutdown := True;

Но я убедился, что мой сборщик хорошо её дополняет. Дело в том что часто нужно создавать временный код, который лень писать по правилам, без утечек. Поэтому я включаю свой сборщик мусора только время от времени, а потом ещё включаю ReportMemoryLeaksOnShutdown – она ловит утечки вроде неудалённых стандартных динамических массивов.

Ещё я почти отказался от обычных динамических массивов в Delphi, заменив их на такие штуки:


TRiAnySimpleArray<MyType> = record
  public
    FCount:integer;
    FItems:tarray<mytype>;
    procedure SetCount(newcount:integer); inline;
    function GetItem(Index:Integer): MyType; inline;
    procedure SetItem(Index:integer; value:mytype); inline;
    property Item[index: integer]: MyType read getItem write setItem; default;
    property Count:integer read FCount write SetCount;
    procedure InitAndSetCount(newcount:integer);
    procedure Initialize;
    procedure Finalize;
  end;


Эти динамические массивы тоже взаимодействуют с моим сборщиком мусора:

procedure TRiAnySimpleArray<MyType>.SetCount(newcount: integer);
  begin
    if poGarbageFinderActive then begin
      if fcount>0 then ProjecTGarbageFinder.MemoryBlockDestroyed(addr(fitems[0]));
    end;

  setlength(fitems,newcount);
  fcount:=newcount;

  if poGarbageFinderActive then begin
    if newcount>0 then ProjecTGarbageFinder.MemoryBlockCreated(addr(fitems[0]),newcount);
  end;

end;


Так вот у меня вопрос к сишникам – как всё это реализовать на C или C++? Я полагаю тут всё должно быть просто.
"Ты должен сделать добро из зла, потому что его больше не из чего сделать". АБ Стругацкие.
Re: Сборщик мусора
От: vsb Казахстан  
Дата: 05.05.19 08:19
Оценка: +12
Я за годы велосипедописания пришёл к выводу, которые многие не поддержат: не надо делать из языка то, чего в нём нет, даже если кажется, что можно. Это вообще ко многим областям относится. Если тебе нужен сборщик мусора — возьми C#. Если тебе нужны nullable типы — возьми Kotlin, а не тыкай @NonNullable в Java на каждый чих. Если тебе нужны исключения — пиши на С++, а не абузь паники в Go. Если тебе нужны иммутабельные структуры, пиши на Elm, а не мучайся на JS с FB Immutable. А на языке надо писать так, как все пишут, как его создатели подразумевали, как стандартная библиотека и качественные примеры написаны. В конечном счёте это лучше. Иначе ты уже создаёшь свой Delphi++, который будет заведомо хуже оригинала (потому что хороший язык способны создать единицы команд в мире). Надо писать, как говорят, согласно лучшим практикам. В том числе это относится, кстати, ко всяким индентациям и форматированиям. Не надо тащить своё мнение, надо просто писать, как пишут все.

Вот что действительно даёт пользу, это инструменты, которые никак не меняют исходный код, но приносят свой профит. Например линтер. Ты можешь писать правильный код, а потом прогонять линтер и получать профит сверху на халяву. А можешь не прогонять, код каким был, таким и останется. Поэтому если ты придумаешь, как свой "сборщик мусора" сделать так, чтобы он просто работал не требуя никаких изменений в программе и никак не влияя на её работу (т.е. просто выводил бы предупреждения, например), чтобы ты его мог легко отключить при желании и всё продолжало работать как работало, вот это будет правильней.
Отредактировано 05.05.2019 9:39 vsb . Предыдущая версия .
Re[2]: Сборщик мусора
От: Khimik  
Дата: 25.05.19 11:38
Оценка:
Здравствуйте, vsb, Вы писали:

vsb>Я за годы велосипедописания пришёл к выводу, которые многие не


vsb>Вот что действительно даёт пользу, это инструменты, которые никак не меняют исходный код, но приносят свой профит. Например линтер. Ты можешь писать правильный код, а потом прогонять линтер и получать профит сверху на халяву. А можешь не прогонять, код каким был, таким и останется. Поэтому если ты придумаешь, как свой "сборщик мусора" сделать так, чтобы он просто работал не требуя никаких изменений в программе и никак не влияя на её работу (т.е. просто выводил бы предупреждения, например), чтобы ты его мог легко отключить при желании и всё продолжало работать как работало, вот это будет правильней.


Ну мне кажется у меня так и есть, когда мой сборщик мне начинает мешать (замедлять программу например), я его отключаю. Можно это делать прекомпиляцией, например tsafeobject=type tobject.

Вот нашлась статья по теме:

https://habr.com/ru/post/282544/

Автор написал похожую вещь на C++, но в итоге отказался от неё из-за специфики его проекта: во-первых, он писал открытый код для других, которым было затруднительно всё это изучать, во-вторых ему понадобились скриптв. Но может, для шароварщиков и игроделов такая вещь — самое то?
"Ты должен сделать добро из зла, потому что его больше не из чего сделать". АБ Стругацкие.
Отредактировано 25.05.2019 11:40 Khimik . Предыдущая версия .
Re: Сборщик мусора
От: MamutArGud  
Дата: 02.06.19 12:11
Оценка:
K>Так вот у меня вопрос к сишникам – как всё это реализовать на C или C++? Я полагаю тут всё должно быть просто.

Если наследовать все от одного объекта, то да, в коакой-то мере несложно. Вон в Qt все наследуется от QObject и соответсвенно имеет собственный «сборщик мусора» (на самом деле подсчет ссылок емнип), так что можно создавать объекты пачками, не волнуясь об утечках памяти. Из-за этого им пришлось переписать половину стандартной библиотеки, потому что Qt очень не любит и не умеет работать с чем-либо вне QObject'а.
Re: Сборщик мусора
От: 0xCAFEDEAD  
Дата: 20.06.19 11:39
Оценка:
Здравствуйте, Khimik, Вы писали:

K>Я уже писал в другой теме про свой кастомный сборщик мусора – класс TSafeObject и объект ProjectGarbageFinder в Delphi. Они выглядит примерно так:

Просто интересно, а этот Делбфи еще не совсе умер что ли?
Re[2]: Сборщик мусора
От: wamaco  
Дата: 20.06.19 20:55
Оценка:
Здравствуйте, 0xCAFEDEAD, Вы писали:

CAF>Просто интересно, а этот Делбфи еще не совсе умер что ли?


Живее всех живых!
Re[3]: Сборщик мусора
От: 0xCAFEDEAD  
Дата: 23.06.19 07:03
Оценка:
Здравствуйте, wamaco, Вы писали:

W>Здравствуйте, 0xCAFEDEAD, Вы писали:


CAF>>Просто интересно, а этот Делбфи еще не совсе умер что ли?


W>Живее всех живых!


А где же он живет ныне? Ну кроме этого топика, каких-нибудь университетах, и у энтузиастов.
Ничего не имею против Паскаля и его детей, но как на этом деньги зарабатывать? Это же не кобол какой-нибудь.
Re[2]: Сборщик мусора
От: Khimik  
Дата: 18.09.19 16:38
Оценка:
Здравствуйте, vsb, Вы писали:

vsb>Я за годы велосипедописания пришёл к выводу, которые многие не поддержат: не надо делать из языка то, чего в нём нет, даже если кажется, что можно. Это вообще ко многим областям относится. Если тебе нужен сборщик мусора — возьми C#. Если тебе нужны nullable типы — возьми Kotlin, а не тыкай @NonNullable в Java на каждый чих. Если тебе нужны исключения — пиши на С++, а не абузь паники в Go. Если тебе нужны иммутабельные структуры, пиши на Elm, а не мучайся на JS с FB Immutable. А на языке надо писать так, как все пишут, как его создатели подразумевали, как стандартная библиотека и качественные примеры написаны. В конечном счёте это лучше. Иначе ты уже создаёшь свой Delphi++, который будет заведомо хуже оригинала (потому что хороший язык способны создать единицы команд в мире). Надо писать, как говорят, согласно лучшим практикам. В том числе это относится, кстати, ко всяким индентациям и форматированиям. Не надо тащить своё мнение, надо просто писать, как пишут все.



Судя по количеству плюсов к вашему посту, боюсь что вы правы. Тогда я предлагаю общими усилиями делать Delphi++. Надеюсь на этом форуме есть немало шароварщиков, предпочитающих этот язык.
Вот мои идеи:
1) Сборщик мусора, как описано;
2) Амперметр для оптимизации;
3) Собственный менеджер памяти;
4) Заменил почти все стандартные динамические массивы на рекорды, т.е. сделал обертки к этим массивам в виде рекордов. С обертками эти массивы взаимодействуют с моим сборщиком мусора и ещё для них стало работать range checking.
5) Практически не использую секцию private, вместо нее ставлю префиксы к названиям полей и функций;
6) Использую стандартные имена однотипных, но сложных комментариев, чтобы заменить одно туду на много вариантов.
"Ты должен сделать добро из зла, потому что его больше не из чего сделать". АБ Стругацкие.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.