堆分配中哪种情况更轻/更重?

时间:2015-08-20 00:01:02

标签: delphi loops memory-management heap-memory

作为a previous answer to another question的后续行动,我对堆分配在循环中的工作方式感到好奇。

举例说明以下两种情况:

声明:

SomeList: TObjectList<TSomething>;

情景1:

begin
  for X := 1 to 10 do
    SomeList[X].DoSomething;
end;

情景2:

var
  S: TSomething;
begin
  for X:= 1 to 10 do begin
    S:= SomeList[X];
    S.DoSomething;
  end;
end;

现在我很好奇的是堆分配在两种情况下的工作原理。场景1在每次循环迭代中直接调用列表项,我想知道它是否每次循环迭代时都会添加到堆和释放。另一方面,第二种情况显然只有一个堆分配,只需声明一个局部变量。

我想知道哪种情况会对堆分配造成更大的负担(导致性能问题的主要原因之一)?

1 个答案:

答案 0 :(得分:6)

  

现在我感到好奇的是堆分配在两种情况下的工作方式。

您的示例中没有堆分配(除非DoSomething()在内部分配内存)。

  

场景1直接调用每个循环迭代中的列表项

情景2也是如此。

  

我想知道它是否会在每次循环迭代时添加到堆和释放。

没有任何东西被添加到堆中。

  

另一方面,第二种情况显然只有一个堆分配,只需声明一个局部变量。

局部变量分配在堆栈上,而不是上。但是,变量可以指向在堆上的内存中。方案2中的S变量确实存在,因为TObject - 派生类总是在堆上分配。 S只是堆栈上的一个局部变量,它指向TSomething对象占用的堆内存。

  

我想知道哪种情况会对堆分配造成更大的负担(导致性能问题的主要原因之一)?

两者都没有,因为您的示例中没有堆分配。