首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Delphi 7,字符串问题

Delphi 7,字符串问题
EN

Stack Overflow用户
提问于 2012-04-12 11:08:52
回答 2查看 1.3K关注 0票数 4

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

谷歌没有帮助,我不能拆解它(没有技能),所以我决定创建一个最小的测试示例,在那里,我可以从内存异常中得到的字符串不到2000 000 000个符号。我不能创造这样的例子,但我创造了一些奇怪的东西:

代码语言:javascript
复制
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.S。这个字符串未注释的示例在3分钟内(从用户模式)将我的Windows 7发送到BSOD。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-04-12 13:34:05

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

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

那是,

代码语言:javascript
复制
s := s + '{' +  b + '}';

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

每次运行这一行时,都有一个内存分配和一个内存释放。即使使用FastMM4,这也可能是缓慢的。但是对于老的MM来说,它可能会非常慢。

2.如何避免减速?

如果您在旧的Delphi中,使用"Borland“内存管理器,分配和重新分配是非常缓慢的。它会破坏很多记忆。

由于内存碎片,以及Borland内存管理器必须对此行的内存分配进行一些缓慢清理,ss[1] := 'd'当然非常慢。

用以下方式更改行:

代码语言:javascript
复制
var ss: string[1];

而且它不会再慢下来了,因为shortstring将在堆栈上分配,堆也不会被使用。

因此,为了避免减速:

  • 使用一个现代内存管理器,比如FastMM4;
  • 使用TStringBuilder-like类,或者是一个很好的旧TMemoryStream,您可以在其中追加数据:您的内存重新分配会少得多,所以它会更快。

3.如何避免内存不足?

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

因此,前一个问题的两个解决方案将解决这个问题。

票数 4
EN

Stack Overflow用户

发布于 2012-04-12 11:13:14

通过执行

代码语言:javascript
复制
s := s + '{' +  b + '}';

在一个长时间运行的循环中,您的内存只会被分割。您很可能有足够的内存来处理字符串,但这还不够。您需要内存是连续的,但是您的分配模式会使这很困难。

通过调用SetLength将字符串预先分配到其最终想要的长度来解决这个问题。

票数 9
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10122338

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档