Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Клуб программистов > Свободное общение
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 18.08.2020, 13:56   #1
Drouge
Пользователь
 
Регистрация: 18.05.2020
Сообщений: 23
По умолчанию Сборщик мусора для Delphi и C++

Здравствуйте, извиняюсь если пишу не в тот раздел, я недавно на этом форуме.
Мне пришла в голову идея сделать сборщик мусора в Delphi. Объявил класс TSafeObject, сделал все мои классы его наследниками. Этот класс на конструкторе обращается к объекту, который запоминает адрес, а на деструкторе ссылка в этом объекте удаляется; после работы программы подсчитываются неудалённые классы:

Код:
type

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

TGarbageFinder=class
private
FObjectsCount:integer;
FObjectsCapacity:integer;

FObjects:array of record
obj:tobject;
CreationTime:tdatetime;
CreationTimeTicks:longword;
Tag:integer;
PosInFullLog:integer;
FirstNum:integer;//Под каким номером был этот объект в самом начале
RandTag:integer;
Debugging:boolean;//Для таких не надо выдавать сообщение об ошибке
end;

FMemoryBlocks:array of record
MemMos:pointer;
BytesCount:integer;
CreationTime:tdatetime;
CreationTimeTicks:longword;
PosInFullLog:integer;
Tag:integer;
end;

FMemoryBlocksCount:integer;
FMemoryBlocksCapacity:integer;

FLogMessages:tstringlist;
FFullLogCount:integer;
FFullLogCapacity:integer;
FFullLog:array of record
LogMesType:integer;
PostTimeTicks:cardinal;
PostTime:tdatetime;
end;
FObjectsSaved:tlist;
FSaveRepFileName:tfilename;
FReport:tstringlist;
FSectionStarted:boolean;
FSectionsCount:integer;
FTwiceDestroyedObjectsCount:integer;
FTotalObjectsNotDestroyedCount:integer;
FTotalMemoryBlocksNotDestroyedCount:integer;
FTotalTwiceDestroyedObjectsCount:integer;
procedure Grow;
procedure GrowFullLog;
procedure GrowMemBlocksArray;
procedure DeleteObject(objnum:integer);
procedure DeleteMemoryBlock(blocknum:integer);
procedure AddObject(obj:tobject; crtime:tdatetime; crtimeticks:longword);
procedure AddMemoryBlock(pos:pointer; bytescount:integer);
function AddMessageToLogMessagesList(str:string):integer;//Возрвщает индекс этой строки в FLogMessages;
procedure AddItemToFullLog(messtypenum:integer);
procedure SetObjectsCapacity(newcapacity:integer);
procedure SetFullLogCapacity(newcapacity:integer);
procedure SetMemoryBlocksCapacity(newcapacity:integer);
function NotDebuggingObjectsCount:integer;//Количество объектов за исключением debugging
public
FReportFileTooBig:boolean;
function SomeGarbageRemaining:boolean;
function FindObject(obj:tobject; direction:tdirection):integer;//-1 если нет
function FindMemoryBlock(pos:pointer; direction:tdirection):integer;
procedure SetObjectTag(obj:tsafeobject; newtag:integer);
procedure AddStringToFullLog(str:string);
procedure StartSection;
procedure FinishSection;
procedure AddToReport(str:string);
procedure ObjectCreated(obj:tobject); overload;
//procedure ObjectCreated(obj:tobject; logstr:string); overload;
procedure ObjectDestroyed(obj:tobject);
procedure MemoryBlockCreated(pos:pointer; bytescount:integer);
procedure MemoryBlockDestroyed(pos:pointer);
procedure PlaceTag(tag:integer);
constructor Create(repfilename:tfilename);
procedure FinalizeReport;
procedure WriteReportToFile;
destructor Destroy; override;
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;
Похожий сборщик мусора был придуман и для C++:

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

Правда автор в итоге отказался от своего сборщика. Я свой использую два года и результатом доволен.

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

Код:
type
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 rroItem[index: integer]: MyType read getItem write setItem; default;
property Count:integer read FCount write SetCount;
procedure InitAndSetCount(newcount:integer);
procedure Initialize;
procedure Finalize;
  end;
Преимущество этих классов в том, что, во-первых, в них есть проверка границ (для динамических массивов в Delphi этой проверки нет), во-вторых они тоже взаимодействуют с моим сборщиком мусора:


Код:
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*sizeof(mytype));
    end;
  end;
Не знаю, насколько это актуально для C.
Drouge вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
сборщик мусора goluzov Общие вопросы C/C++ 2 29.04.2012 15:25
Сборщик мусора для отдельного класса _-Re@l-_ Общие вопросы C/C++ 17 13.08.2011 12:30
Сборщик мусора в динамическом списке Homutova_Julia Помощь студентам 4 17.06.2011 19:09
Не могу организовать сборщик мусора Homutova_Julia Помощь студентам 5 08.06.2011 13:22
Опрос: Сборщик мусора Пепел Феникса Общие вопросы по программированию, компьютерный форум 15 20.04.2011 19:19