Q&A

  • 메모리 무한 증가 문제ㅠ.ㅠ
<!--CodeS-->
// 추출된 데이터값 체크 ////////////////////////////////////////////////////
            try
              ZZMySqlQuery1 := TZZMySqlQuery.Create(nil);
              ZZMySqlQuery1.Database := ZZMySqlDatabase1;
              ZZMySqlQuery1.Transaction := ZZMySqlTransact1;

              ZZMySqlQuery1.Sql.Clear;
              queryStr := 'Select ipdata_code From ipdata Where ipdata_code=''' + gcodeTemp1 + ''' limit 1';
              ZZMySqlQuery1.Sql.Add(queryStr);

              try
                ZZMySqlQuery1.Open;
                ZZMySqlQuery1.First;
              except
                memo2.Lines.Add('SQL체크실패[' + gcodeTemp1 + ']');
              end;

            finally
              ZZMySqlQuery1.Sql.free;
            end;

            count := ZZMySqlQuery1.FieldByName('ipdata_code').asString;
            if count = '' then
              begin
                memo1.Lines.Add( gcodeTemp1 );
              end;

            ZZMySqlQuery1.close;

<!--CodeE-->

안녕하세요.
위에 소스 코드를 루프내에서 돌리고 있는데요.

메모리가 최고 50~60 메가 까지 올라가는군요.
메모리 해제가 아예 안되는 것 같습니다.

혹시 몰라서 저 부분 주석처리하고 루프 돌리니 메모리 증감이 없더라구요.
답변 부탁드립니다.
3  COMMENTS
  • Profile
    민스맘 2007.01.23 20:19



    제일 마지막에 ZZMySqlQuery1.Free; 를 넣어보세요....
    query 를 생성하는 부분은 있는데 소멸시키는 부분없이 계속 생성을 시키고 있어서 그렇습니다.

  • Profile
    이하나 2007.01.23 22:15

    이게 참 어이없는 게요..
    ZZMySqlQuery1.Free 를 처리해었는데...컴파일은 정상적으로 완료됩니다.

    그런데 실행중 이벤트를 처리하려면 해당 부분(ZZMySqlQuery1.Free) 부분에서 에러가 발생되거든요.

    그래서 일부러 빼놓고 작업을 했었는데, 이해할 수가 없습니다.ㅠ.ㅠ

  • Profile
    박정훈 2007.01.24 00:12
    <!--CodeS-->
    try
                  ZZMySqlQuery1 := TZZMySqlQuery.Create(nil);
                  ZZMySqlQuery1.Database := ZZMySqlDatabase1;
                  ZZMySqlQuery1.Transaction := ZZMySqlTransact1;

                  ZZMySqlQuery1.Sql.Clear;
                  queryStr := 'Select ipdata_code From ipdata Where ipdata_code='+'''' + gcodeTemp1 +''''+' limit 1';
                  ZZMySqlQuery1.Sql.Add(queryStr);

                  try
                    ZZMySqlQuery1.Open;
                    ZZMySqlQuery1.First;
                  except
                    memo2.Lines.Add('SQL체크실패[' + gcodeTemp1 + ']');
                  end;

                count := ZZMySqlQuery1.FieldByName('ipdata_code').asString;
                if count = '' then
                  begin
                    memo1.Lines.Add( gcodeTemp1 );
                  end;

                ZZMySqlQuery1.close;

    finally
               ZZMySqlQuery1.free

    end

    <!--CodeE-->

    코드를 잘보세요..  어딜 잘못하셨는지 아시겠죠?
    사실 이것도 잘못된 소스이긴합니다.. except 가 발생한다면  count := ZZMySqlQuery1.FieldByName('ipdata_code').asString;  이 부분이 동작을 안할테니 에러가 발생하겠죠.. 뭐 여튼 그건 그렇고 어쨌든 중요한건 free 를 안해줘서 메모리가 증가하는거니까요


    문제의 원인은  엉뚱한 위치에 ZZMySqlQuery1.SQL.free  라는 구문이 엉뚱하게 사용되었기 때문입니다.
    ZZMySqlQuery1.SQL.free 라는 구문은 전혀 필요없는 부분이구요
    위의 코드처럼 맨위의 try 와 아래의 finally 부분에 ZZMySqlQuery1.free 가 들어가야지 정상적으로 생성과 소멸의 위치가  지정되는거죠


    두번째... 루프를 도는데 왜 ZZMySqlQuery1 를 계속 생성을 할 필요가 있나요?  한 루틴에서 1개의 ZZMySQLQuery 를 생성해서 이넘을 계속사용하다가 마지막에 파괴시키면 되는데 그렇게 하지 않으시고 이걸 동적으로 자꾸 생성시키니 메모리가 계속 증가할수 밖에 없죠
    전체적으로 한번 생성해서 쓰다가 한번 파괴하는거랑,  루프 한번 돌때마다 한번생성, 한번파괴하는거랑 호율성이 어떤게 더 좋을지 한번 생각을 해보세요.


    <!--CodeS-->
    procedure TForm1.TestButtonClick(Sender:TObject);
    var i : Integer;
         queryStr, count : String;
         ZZMySqlQuery1 : TZZMySqlQuery
    begin

      try
                  ZZMySqlQuery1 := TZZMySqlQuery.Create(nil);
                  ZZMySqlQuery1.Database := ZZMySqlDatabase1;
                  ZZMySqlQuery1.Transaction := ZZMySqlTransact1;

                  queryStr := 'Select ipdata_code From ipdata Where ipdata_code='+'''' + gcodeTemp1 +''''+' limit 1';
                  ZZMySqlQuery1.Sql.Clear;
                  ZZMySqlQuery1.Sql.Add(queryStr);

                      try
                         ZZMySqlQuery1.Open;
                         ZZMySqlQuery1.First;
                      except
                         memo2.Lines.Add('SQL체크실패[' + gcodeTemp1 + ']');
                      end;

                    // 쿼리의 결과를 순차적으로 받아올려면
                    for i:=0 to ZZMySQLQuery1.RecordCount-1 do begin
                             count := ZZMySqlQuery1.FieldByName('ipdata_code').asString;

                             if count = '' then
                              begin
                                  memo1.Lines.Add( gcodeTemp1 );
                              end;

                         ZZMySqlQuery1.Next;
                    end;
                        
                   ZZMySqlQuery1.close;

       finally
               ZZMySqlQuery1.free
       end;

    end;

    <!--CodeE-->



    gcodeTemp1 이라는 인자를 계속 변경해가면서 루프를 돌릴려면 이렇게 펑션을 만들어야 하겠죠. .First/ .Next 는 여러개의 쿼리결과를 가져오기 위한 것이고 1개만 가져오려면 그냥 .Open 만 해주면 됩니다.


    <!--CodeS-->
    function Tform1.ReturnQueryResult(ZZMySqlQuery1 : TZZMySqlQuery; gcodeTemp1 : String): String;
    var
      queryStr, count : String;
    begin

         queryStr := 'Select ipdata_code From ipdata Where ipdata_code='+'''' + gcodeTemp1 +''''+' limit 1';
          ZZMySqlQuery1.Sql.Clear;
          ZZMySqlQuery1.Sql.Add(queryStr);

          try
             ZZMySqlQuery1.Open;
             count := ZZMySqlQuery1.FieldByName('ipdata_code').asString;

              if count = '' then  begin
                            Result := gcodeTemp1;
             end;                  
           except
                            Result := '';
           end;
    end;



    procedure Tform1.TestButtonClick(Sender:Tobject);
    var i : Integer;
         ZZMySqlQuery1 : TZZMySqlQuery
         RetTemp : String;
    begin

      // 한번만 생성시키고 이넘을 계속사용해서 루프를 돌리게 한다
      try
                  ZZMySqlQuery1 := TZZMySqlQuery.Create(nil);    // 여기서 생성
                  ZZMySqlQuery1.Database := ZZMySqlDatabase1;
                  ZZMySqlQuery1.Transaction := ZZMySqlTransact1;

                  // 여기서 루프를 돌린다
                  for i:=0 to 100 do begin
                         RetTemp  := ReturnQueryResult(ZZMySqlQuery1, intTostr(i) ):
                        memo1.Lines.Add( RetTemp );
                  end;

      finally
                  ZZMySqlQuery1.free;   // 여기서 파괴
      end;
    end;

    <!--CodeE-->


    대충 이정도 정리가 되겠군요

    이 부분은 제가 일전에 올려드린 예제소스에도 그대로 나와있는 부분인데요..  소스를 제대로 안보셨나 봅니다.. 쩝