String Delphi7,字符串问题
在我的项目中,我遇到了字符串“内存不足异常”的问题,MM没有被使用。当字符串长度达到2 300000个符号时,问题就出现了。尽管有足够的内存,并且在代码的同一部分中,我可以创建一个包含100000000个字符的sting 谷歌没有帮助,我无法分解它(没有技能),所以我决定创建一个最小的测试示例,在这个示例中,我可以获得小于200000个符号的字符串的内存异常。我不能创造这样的例子,但我创造了一些奇怪的东西:String Delphi7,字符串问题,string,delphi,assembly,delphi-7,String,Delphi,Assembly,Delphi 7,在我的项目中,我遇到了字符串“内存不足异常”的问题,MM没有被使用。当字符串长度达到2 300000个符号时,问题就出现了。尽管有足够的内存,并且在代码的同一部分中,我可以创建一个包含100000000个字符的sting 谷歌没有帮助,我无法分解它(没有技能),所以我决定创建一个最小的测试示例,在这个示例中,我可以获得小于200000个符号的字符串的内存异常。我不能创造这样的例子,但我创造了一些奇怪的东西: program Project2; {$APPTYPE CONSOLE} uses
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.
这段代码运行良好。它只是通过一些额外的操作将某些内容添加到全局字符串中。问题是,如果取消对标记字符串的注释,它将显著减慢(无论是否进行优化)。考虑到这个赋值在100001次迭代中只有一次,它不能减慢速度
问题:
p、 p.s未注释字符串的示例在3分钟内(从用户模式)将我的Windows 7发送到BSOD。通过执行以下操作分配字符串
s := s + '{' + b + '}';
在一个长时间运行的循环中,它只会使你的记忆片段化。您可能有足够的内存来存储字符串,但这还不够。您需要内存是连续的,但是您的分配模式会使这变得很困难
通过调用
SetLength
1,将字符串预分配到其最终所需长度,从而解决此问题。Delphi中的默认字符串如何工作?
每次受影响时(通过:=
)都会分配一个新的字符串
就是
s := s + '{' + b + '}';
将为s+'{'+b+'}'分配一个字符串
,然后将其复制到变量s
每次运行这一行时,都有一个内存分配和一个内存释放。这可能很慢,即使使用FastMM4。但对于老MM来说,速度可能会非常慢
2。如何避免减速?
如果您使用的是旧的Delphi,使用“Borland”内存管理器,则分配和重新分配非常缓慢。它会使记忆碎片化很多
ss[1]:='d'
当然非常慢,这是由于内存碎片,而且Borland内存管理器必须对此行的内存分配进行一些缓慢的清理
将行更改为:
var ss: string[1];
而且它不会再慢下来,因为shortstring
将在堆栈上分配,而堆不会被使用
因此,为了避免减速:
- 使用现代内存管理器,如FastMM4李>
- 使用
TStringBuilder
类,或者使用一个好的、旧的TMemoryStream
在其中添加数据:内存重新分配会少得多,因此速度会快得多
3。如何避免内存不足?
内存不足错误来自内存碎片
所以前一个问题的两个解决方案将解决这个问题