【问题标题】:Delphi 7, strings problemsDelphi 7,字符串问题
【发布时间】:2012-04-12 11:08:52
【问题描述】:

在我的项目中,我遇到了字符串“内存不足异常”的问题,没有使用 MM。问题显示当字符串的长度达到 2 300,000 个符号时。尽管有足够的内存并且在同一部分代码中,我可以创建一个包含 100,000,000 个字符的字符串。

Google 没有帮助,我无法反汇编它(没有技能),所以我决定创建一个最小的测试示例,我可以在少于 2 000 000 000 个符号的字符串上出现内存不足异常。我无法创建这样的示例,但我创建了一些奇怪的东西:

program Project2;
{$APPTYPE CONSOLE}
uses
   SysUtils;

var s : string;
    k : integer;

function b : string;
begin
 result := 'f';
end;

procedure c;
var ss : string;
begin
  s := s + '{' +  b + '}';
  ss :=  'a';

  if k mod 100001 = 0 then
  begin
     // ss[1] := 'd';    // uncoment me
     write(k mod 10);
  end;

  inc(k);
end;

begin
  while true do c;
end.

此代码运行良好。它只是通过一些额外的操作向全局字符串添加一些内容。问题是,如果您取消注释标记的字符串,它会显着减慢(无论是否优化)。考虑到这个赋值在 100,001 次迭代中一次,它一定不会减慢。

问题:

  1. Delphi 中的默认字符串如何工作?

  2. 如何避免减速?

  3. 如何避免内存不足?

附:如果我将 FastMM 包含到主项目中,错误就会消失 p.p.s 未注释字符串的示例在 3 分钟内(从用户模式)将我的 Windows 7 发送到 BSOD。

【问题讨论】:

    标签: string delphi assembly delphi-7


    【解决方案1】:

    通过做分配字符串

    s := s + '{' +  b + '}';
    

    长时间运行的循环只会使您的记忆碎片化。您可能对字符串有足够的内存,但这还不够。您需要内存是连续的,但您的分配模式会让这变得困难。

    通过调用SetLength 将字符串预分配到最终所需的长度来解决问题。

    【讨论】:

      【解决方案2】:

      1. Delphi 中的默认字符串是如何工作的?

      每次受到影响时都会分配一个新的string(通过:=)。

      也就是说,

      s := s + '{' +  b + '}';
      

      将为s + '{' + b + '}';分配一个string,然后将其复制到变量s

      每次运行此行时,都会分配一次内存,释放一次内存。这可能会很慢,即使使用 FastMM4。但是对于年长的 MM,它可能会缓慢。

      2。如何避免减速?

      如果您在旧的 Delphi 中,使用“Borland”内存管理器,分配和重新分配非常慢。而且它会使内存碎片化很多。

      由于内存碎片,ss[1] := 'd' 肯定非常慢,而且 Borland 内存管理器必须对该行的内存分配进行一些缓慢的清理。

      换行:

      var ss: string[1];
      

      而且它不会再变慢了,因为shortstring 将被分配到堆栈上,并且不会使用堆。

      所以为了避免减速:

      • 使用现代内存管理器,例如 FastMM4
      • 使用类似TStringBuilder 的类,或旧的TMemoryStream 来追加数据:内存重新分配会少得多,因此速度会快得多

      3.如何避免内存不足?

      内存不足错误来自内存碎片。

      所以上一个问题的两个解决方案将解决这个问题。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-07-02
        • 1970-01-01
        • 2012-12-12
        • 1970-01-01
        • 2014-08-11
        • 1970-01-01
        • 2011-01-03
        相关资源
        最近更新 更多