New和Dispose在内部做什么?

Blu*_*erk 5 delphi

我想知道在调用New和Disposed时内部会发生什么.Delphi的帮助提供了一个合理的解释,但是如果一个人会写一个自己的New和Dispose,那该怎么办呢?哪个方法在内部调用两个方法还是全部组装?

我不打算写自己的New和Dispose.我对这两种方法的内部工作非常好奇.

Dav*_*nan 9

New 执行以下操作:

  1. 通过调用为新对象分配内存GetMem.
  2. 初始化任何托管字段,如字符串,接口,动态数组等.

Dispose 颠倒了这个:

  1. 完成托管字段.
  2. 通过调用来释放内存FreeMem.

请注意这两个NewDispose内在功能.这意味着编译器具有额外的知识,并且能够根据所讨论的类型改变它们的实现方式.

例如,如果类型没有托管字段,则New优化为简单调用GetMem.如果类型具有托管字段,则New通过调用来实现,该调用System._New执行上述步骤.

实施Dispose方式大致相同.FreeMem对非托管类型的简单调用,以及对System._Dispose其他方式的调用.

现在,System._New实现如下:

function _New(Size: NativeInt; TypeInfo: Pointer): Pointer;
begin
  GetMem(Result, Size);
  if Result <> nil then
    _Initialize(Result, TypeInfo);
end;
Run Code Online (Sandbox Code Playgroud)

请注意,PUREPASCAL为了简单起见,我刚刚展示了该变体.这个电话GetMem很简单.呼吁System._Initialize更多涉及.它使用TypeInfo参数来查找对象中包含的所有托管类型并初始化它们.这是一个递归过程,因为,例如,记录可能包含本身是结构类型的成员.您可以在RTL源中查看所有血腥细节.

至于System._DisposeSystem._Finalize,然后调用FreeMem.而且System._Finalize是非常相似,System._Initialize不同的是它最终确定管理类型,而不是初始化它们.

长期以来,对于性能敏感的Delphi用户来说,这是一个bug,System._Initialize并且System._Finalize以运行时类型信息为基础以这种方式实现.这些类型在编译时是已知的,编译器可以编写为内联初始化和最终化,这将导致更好的性能.