“111”大概占8个字节,应该还有一个指针4字节,共12字节,每秒50个,每秒增加600个字节,一分钟36k,十分钟360k,可能还有其他开销,到500k也很正常。

解决方案 »

  1.   

    如果a没有释放一直调用add方法内存会一直增加,你这样的结果是
    111
    111
    111
    ...
      

  2.   


    我的困惑是:
    我用idhttp获取网页中的链接,然后将这些链接以字符串的形式存放到一个tstringlist中,每个tstringlist成员字符串长度不会超过100个字符。我注意到:当tstringlist ADD到500个的时候,程序占用内存增加了4-5M,500个100字符的字符串有占这么大空间吗?程序其他部分都停止运行了,不存在其他消耗内存的东东了,这是为什么?
      

  3.   

    Delphi的字符串包括一个标志字符串长度的无符号整数,有8位和32位两种,一般是32位,4字节,后面还有一个字节的0以兼容c。
      

  4.   

    说一个丢人的事,一次程序里面额List不断Add一个对象,但是处理的功能(取出指针,处理、释放、删除)没有跑起来,一天下来13个小时,我查看该进程的虚拟内存达到1.4G.
      

  5.   

    我的困惑是:
    我用idhttp获取网页中的链接,然后将这些链接以字符串的形式存放到一个tstringlist中,每个tstringlist成员字符串长度不会超过100个字符。我注意到:当tstringlist ADD到500个的时候,程序占用内存增加了4-5M,500个100字符的字符串有占这么大空间吗?程序其他部分都停止运行了,不存在其他消耗内存的东东了,这是为什么?
      

  6.   

    Delphi的 TStringList部分的源码:
    TStringList中包括一个称为FList的指针,其类型为Point Of TStringItem,而TStringItem这个类型的定义为
      TStringItem = record
        FString: string;
        FObject: TObject;
      end;
    该结构体最小需要占8个额外的字节。
    此外,
    procedure TStringList.Grow;
    var
      Delta: Integer;
    begin
      if FCapacity > 64 then Delta := FCapacity div 4 else
        if FCapacity > 8 then Delta := 16 else
          Delta := 4;
      SetCapacity(FCapacity + Delta);
    end;
    表明TStringList的最大可能会有1/4的空余容量多出来,也就是说,LZ分配的500个String,其实开在内存中的结构可能是650个。
    但是这一点差异应当不足以成为内存占用增加4~5M的理由。
    所以会不会是idhttp来抓链接的过程中发生了内存泄露状况,譬如说PChar没有释放掉之类的?或者是内存碎片太多?
      

  7.   

    以下是抓取的过程,看看有无问题?function findbt._Get(var url,scookie : String;var idh:tidhttp) : String;
    var
       stream,outstream : TMemoryStream;
       decomp : TIdCompressorZLibex;
       resp : TStringlist;
    begin
         try
             stream := TMemoryStream.Create;
             resp := TStringList.Create;
             idh.Request.CustomHeaders.Text :=scookie;
             idh.Get(url,stream);
             stream.Position := 0;
             if AnsiCompareText('gzip',idh.Response.ContentEncoding) = 0 then
             begin
             try
                  decomp := TIdCompressorZLibex.Create(nil);
                  outstream := TMemoryStream.Create;
                  decomp.DecompressGZipStream(stream,outstream);
                  outstream.Position := 0;
                  resp.LoadFromStream(outstream);
              finally
                  freeandnil(decomp);
                  freeandnil(outstream);
              end;
             end
             else
                 resp.LoadFromStream(stream);
             Result := resp.Text;
             idh.Disconnect ;
             freeandnil(stream);
             freeandnil(resp);
         except
              idh.Disconnect ;
              freeandnil(stream);
              errorflag:=1;
              freeandnil(resp);
         end;
    end;
      

  8.   

    delphi的内存释放不是把内存返回给系统,而是标记为可用,下次申请时继续使用,所以你会感觉申请的内存不断的增大
      

  9.   

    一方面 Delphi的内存管理器不会立刻回收,而是有自己的调度规则.
    另一方面,新的内存块未必就是你给他那么大,他有一个对齐方式.比如4KB对齐.你不停的分配,实际上会产生比较多的碎块.
    还有内存管理器管理的时候每个内存块都会有一个描述信息.Delphi的默认是用链表管理的.大量的小块数据就会产生比较多的链表节点,每个节点再有一点描述信息.当然会大.VC一般是放在负偏移有一个描述块,结果是一样的.
      

  10.   

    程序中需要储存量比较大的字符串,存放在tstringlist和数组里哪个比较好一点?如果需要频繁使用tstringlist,是对其频繁free-creat好呢?还是不断clear使用好呢?谢谢