我写了一个函数,根据查询条件从数据库中查找照片数据,如果有的话,就写入文件中,可是我发现了很严重的问题:随着查询的次数增加(10000左右),内存的使用是逐步上升达到34-40M之间,直到报[HEC][ODBC XXX Driver] Memory managerment error,程序中止。如果去掉查询的语句,直接读取一个JPG文件,就没有问题,各位帮忙看看,到底是什么问题了,如何解决了,很急的,如果分数不够,还可以加
函数如下:
function TfrmMain.SeachDictionary_Stream(const FieldValue,
  TableName: String):Boolean;
var
   strSql: String;
   strTemp: string;
   intCompress: Integer; //ÍƼöµÄѹËõ±¶ÂÊ
   TempStream: TmemoryStream;
   PicQuery:   TQuery;
begin
   Result := False;   TempStream := nil;
   PicQuery := nil;   strSql := 'Select BMP,JPEG from xp where id=XXXXX';
**********************************************
   try
      PicQuery := TQuery.Create(Self);
      PicQuery.DatabaseName := HDBconner.DatabaseName;
      PicQuery.SQL.Text:=strSql;
      PicQuery.Open;
      if PicQuery.Eof then Exit;
      try        TempStream := TMemoryStream.Create;
        if DicQuery.Fields[0].IsNull then   
           if DicQuery.Fields[1].IsNull then  Exit
        else
           (DicQuery.FieldByName('JPEG') as TBlobField).SaveToStream(TempStream)
        else
           (DicQuery.FieldByName('BMP') as TBlobField).SaveToStream(TempStream);
*****************************************************************
        strTemp := ExtractFilePath(paramstr(0));        if not Unit_ComPressBMP.GetPhotoAndSaveFile(strTemp, TempStream,intCompress) then
             Exit;
        Result := True;
      finally
         TempStream.Free ;
         TempStream := nil;
      end;      if not Result then Exit;      if not Unit_ComPressBMP.CompressImage(strTemp, true, intCompress) then
           Exit;      Result := True;
   finally
      PicQuery.Active := False;
      FreeAndNil(PicQuery);
   end;
end;

解决方案 »

  1.   

    我覺得問題出在你第二個TRY...Finally...End 時釋入資料出了問題,因為你在第二層的TRY語句中使用了Exit方法,但是在第二層中退出時隻會執行第二個Finally中的語句,而第一層中的Query控件並沒有釋放第一層TRY指:
      try
          PicQuery := TQuery.Create(Self);第二層指:
      try
          TempStream := TMemoryStream.Create;
      

  2.   

    function TfrmMain.SeachDictionary_Stream(const FieldValue,
      TableName: String):Boolean;
    var
       strSql: String;
       PicQuery:   TQuery;
    begin
       Result := False;   PicQuery := nil;   strSql := 'Select BMP,JPEG from xp where id=XXXXX';
       try
          PicQuery := TQuery.Create(Self);
          PicQuery.DatabaseName := HDBconner.DatabaseName;
          PicQuery.SQL.Text:=strSql;
          PicQuery.Open;
         
       finally
          PicQuery.Active := False;
          FreeAndNil(PicQuery);
       end;
    end;
    我现在把函数中与数据查询的代码全部去掉了,还是一样的,内存越来越多
    我连接的是一个叫鸿达的数据库(他自己的数据库隐形)
      

  3.   


       PicQuery := TQuery.Create(Self);
       Try
          PicQuery.DatabaseName := HDBconner.DatabaseName;
          PicQuery.SQL.Text:=strSql;
          PicQuery.Open;
       finally
          PicQuery.Active := False;
          PicQuery.Free;
       end;  Try語句放在Create建立語句之後
      

  4.   

    如鸿达六代提供的ODBC方式访问,我用ADO方式连接就肯定不能释放,分析的结果是数据本身的问题,建议参照鸿达的技术资料用ODBC API方式访问(原始资料是VC的,且不一定能解决问题,我没试).实在不行直接分析数据文件,一般没加密
      

  5.   

    function TfrmMain.SeachDictionary_Stream(const FieldValue,
      TableName: String):Boolean;
    var
       strSql: String;
       strTemp: string;
       intCompress: Integer; //ÍƼöµÄѹËõ±¶ÂÊ
       TempStream: TmemoryStream;
       PicQuery:   TQuery;
    begin
       Result := False;   TempStream := nil;
       PicQuery := nil;   strSql := 'Select BMP,JPEG from xp where id=XXXXX';
    **********************************************
       try
          PicQuery := TQuery.Create(Self);
          PicQuery.DatabaseName := HDBconner.DatabaseName;
          PicQuery.SQL.Text:=strSql;
          PicQuery.Open;
          if PicQuery.Eof then Exit;
          try        TempStream := TMemoryStream.Create;
            if DicQuery.Fields[0].IsNull then   
               if DicQuery.Fields[1].IsNull then
               begin
                 TempStream.Free ;
                 TempStream := nil;
                 PicQuery.Active := False;
                 FreeAndNil(PicQuery);
                 Exit;
               end        else
               (DicQuery.FieldByName('JPEG') as TBlobField).SaveToStream(TempStream)
            else
               (DicQuery.FieldByName('BMP') as TBlobField).SaveToStream(TempStream);
    *****************************************************************
            strTemp := ExtractFilePath(paramstr(0));        if not Unit_ComPressBMP.GetPhotoAndSaveFile(strTemp, TempStream,intCompress) then
          begin
               TempStream.Free ;
               TempStream := nil;
               PicQuery.Active := False;
               FreeAndNil(PicQuery);
               Exit;
          end;
            Result := True;
          finally
             TempStream.Free ;
             TempStream := nil;
          end;      if not Result then 
          begin
               PicQuery.Active := False;
               FreeAndNil(PicQuery);
               Exit;
          end;
          if not Unit_ComPressBMP.CompressImage(strTemp, true, intCompress) then
          begin
               PicQuery.Active := False;
               FreeAndNil(PicQuery);
               Exit;
          end;      Result := True;
       finally
          PicQuery.Active := False;
          FreeAndNil(PicQuery);
       end;
    end;试一下
      

  6.   

    To  hch_45(んこん) :
    你把鸿达六代的数据库找来试一下就知道了
      

  7.   

    To  hch_45(んこん) :
       谢谢你的回复,我昨天弄到鸿达六代的数据库的资料,用他自带的程序反复查询一个SQL语句,就发现存在内存没有释放的问题,我想原因出在鸿达六代的数据库服务程序上,
       我把函数改成以下代码:只是打开Query就关闭,还是有问题的
       PicQuery := TQuery.Create(Self);
       Try
          PicQuery.DatabaseName := HDBconner.DatabaseName;
          PicQuery.SQL.Text:=strSql;
          PicQuery.Open;
       finally
          PicQuery.Active := False;
          PicQuery.Free;
       end;
      

  8.   

    试一试:
      PicQuery := TQuery.Create(nil);
       Try
          PicQuery.DatabaseName := HDBconner.DatabaseName;
          PicQuery.SQL.Text:=strSql;
          PicQuery.Open;
       finally
          PicQuery.Active := False;
          PicQuery.Free;
       end;