Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Delphi para la web (https://www.clubdelphi.com/foros/forumdisplay.php?f=51)
-   -   Consulta sobre Web services y Delphi (https://www.clubdelphi.com/foros/showthread.php?t=79452)

Gercondi 05-07-2012 23:36:57

Consulta sobre Web services y Delphi
 
Saludos a todos los que hacen parte de este foro.

Tengo una aplicación que contiene un modulo cliente y uno servidor. El modulo de servidor lee cada 5 segundos información de varios web services y la almacena en unos Tclientdataset, para que el modulo cliente pueda utilizar estos datos.

Mi duda es: Es normal que aún cuando estoy liberando (con Free()) todos los objetos que se crean (con Create()) para el llamado a los webservices la memoria virtual del proceso crezca aproximada mente un mega cada 2 horas?

Uno de los procesos que mas hace crecer la memoria virtual es el siguiente:

Código Delphi [-]
procedure LlamadosWS.getOperadores;
var
  L_SPRCMXCRAFT: SPRCMXCRAFTQuery;
  xORGID, xCRAFT : SPRCMXCRAFT1.Array_Of_MXStringQueryType;
  ListaOperadores : SPRCMXCRAFTSet;
  I : integer;
  op_HTTPRIO : THTTPRIO;
begin
  try
  L_SPRCMXCRAFT := SPRCMXCRAFTQuery.Create;

  SetLength(xORGID,1);
  xORGID[0] := SPRCMXCRAFT1.MXStringQueryType.Create;
  xORGID[0].&operator := SPRCMXCRAFT1.QueryOperatorType.igual;
  xORGID[0].Text := _OrgID;

  L_SPRCMXCRAFT.LABORCRAFTRATE := SPRCMXCRAFT1.LABORCRAFTRATE3.Create;
  L_SPRCMXCRAFT.LABORCRAFTRATE.ORGID := xORGID;


  SetLength(xCRAFT,1);
  xCRAFT[0] := SPRCMXCRAFT1.MXStringQueryType.Create;
  xCRAFT[0].Text := _ESPECIALIDADES;

  L_SPRCMXCRAFT.LABORCRAFTRATE.CRAFT := xCRAFT;


  op_HTTPRIO := THTTPRIO.Create(nil);
  op_HTTPRIO.HTTPWebNode.UserName := Datamodule1.UsuarioCFZ;
  op_HTTPRIO.HTTPWebNode.Password := Datamodule1.PasswordCFZ;


  ListaOperadores := GetSPRCMXCRAFTPortType(False,'',op_HTTPRIO).QuerySPRCMXCRAFT(L_SPRCMXCRAFT);

  L_SPRCMXCRAFT.Free;
  xORGID[0].Free;
  xCRAFT[0].Free;

  with DataModule2 do
  begin

    CDS_Operadores_WS.EmptyDataSet;
    CDS_Operadores_WS.Close;
    CDS_Operadores_WS.Open;

    Datamodule2.LimpiarCDS(CDS_Operadores_WS);

    for I := 0 to Length(ListaOperadores)  - 1 do
    begin

      try
        if ListaOperadores[i].LABOR[0].STATUS.text = 'ACTIVO' then
        begin
            try
              CDS_Operadores_WS.InsertRecord([ListaOperadores[i].LABORCODE.text,
                                 ListaOperadores[i].LABOR[0].PERSON[0].FIRSTNAME.Text + ' ' + ListaOperadores[i].LABOR[0].PERSON[0].LASTNAME.Text,
                                 ListaOperadores[i].CRAFT.text ,
                                 ListaOperadores[i].LABOR[0].PERSON[0].STATUS.Text,
                                 ListaOperadores[i].LABOR[0].PERSONID.Text]);
            finally
             ListaOperadores[i].Free;
            end;

        end;
      except
        Continue;
      end;

    end;
  end;
  finally
     ListaOperadores := nil;
  end;
end;

Ñuño Martínez 06-07-2012 22:01:18

Es muy difícil responder. Sin embargo, he visto que al final asignas un nil a una variable. Recuerda que con eso no liberas memoria.

Me han recomendado muchas veces la herramienta Valgrind, aunque nunca la he usado por vagancia. Quizá te sirva para encontrar dónde reserva memoria que luego no libera.

clauxs88 20-07-2016 17:27:00

Aumenta la Memoria Virtual al utilizar el WebService
 
Al igual que el colega @Gercondi, tengo un Ws que corre entre los servicios de Windows y al realizar las tareas de consumir parametros y devolver resultados el Proceso crece y sigue creciendo a menos que cada tanto reinicie mi Servicio con un net restart WSDemonConuslta; esto pasa inclusive cuando libero los objetos que cree en el proceso con variable:=nil; variable.Free, pero sin importancia.

Algún aporte?

Ñuño Martínez 21-07-2016 12:21:26

Como dije hace cuatro años, es difícil responder. Y también, asignar "nil" no libera memoria. El siguiente código no libera memoria:
Código Delphi [-]
  Objecto := nil;
  Objeto.Free;
Es más, te dará un error puesto que estás intentando llamar a un método de un objeto que no existe (el objeto nil no existe). El código debería ser este:
Código Delphi [-]
  Objeto.Free;
  Objeto := nil;

O lo que es lo mismo:
Código Delphi [-]
  FreeAndNil (Objeto);

AgustinOrtu 21-07-2016 19:32:12

Si invocas a free sobre un objeto que es nil no se eleva una excepción

Ñuño Martínez 21-07-2016 22:37:06

Cita:

Empezado por AgustinOrtu (Mensaje 507094)
Si invocas a free sobre un objeto que es nil no se eleva una excepción

¿Seguro? Me parece recordar que sí provoca un error de ejecución por memoria re-liberada o algo así. Aunque puede que esto sea algo exclusivo de Free Pascal. :confused:

AgustinOrtu 22-07-2016 06:13:22

Totalmente seguro

El metodo free esta implementado asi (o muy similar, sacando los IFDEF segun la plataforma)

Código Delphi [-]
procedure TObject.Free;
begin
  if Self <> nil then
    Destroy;
end;

Esto es totalmente seguro, jamas te va a dar error:

Código Delphi [-]
var
  Obj: TObject;
begin
  Obj := nil;
  while True do
    Obj.Free; 
end;

Ahora, el problema es que el destructor no deja la instancia "limpia" (no asigna nil cuando termina, no deja la memoria en 0000)

Esto si te eleva una excepcion AcessViolation:

Código Delphi [-]
var
  Obj: TObject;
begin
  Obj := TObject.Create;
  Obj.Free; // todo bien
  Obj.Free; // AccessViolation
end;

Ñuño Martínez 22-07-2016 12:21:45

Ok. Ahora sí me quedó claro. Será entonces eso, que no "limpio" la variable de referencia. Gracias. :)


La franja horaria es GMT +2. Ahora son las 17:16:02.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi