Ir para conteúdo
  • Cadastre-se

dev botao

  • Este tópico foi criado há 4860 dias atrás.
  • Talvez seja melhor você criar um NOVO TÓPICO do que postar uma resposta aqui.

Recommended Posts

Postado

Olá.

O componente ACBrSintegra está gerando um MemoryLeak.

Na procedure abaixo, o problema está corrigido.

Acontece no comando ADD. O mesmo faz uma verificação se o produto já foi adicionado na classe.

Se o mesmo não foi, insere. Caso o produto já foi incluído, deve-se dar um free no objeto.

function TRegistros75.Add(Obj: TRegistro75): Integer;

begin

  Result := GetRegistroExiste(Obj.Codigo) ;

  if Result < 0 then

     Result := inherited Add(Obj)

  else

     Obj.Free;

end;

Atenciosamente.

Jéter Rabelo Ferreira

ACBrSintegra.pas

------------------------------------------------

Jéter Rabelo Ferreira
Campestre/MG

  • Consultores
Postado

Ahh rapaz é mesmo hein. Não tem necessidade de deixar o objeto "Obj" na memória se já existe um outro registro com o mesmo código.

Não lembro se tem mais alguma classe que tem um add que verifica a existência. Se tiver seria bom dar uma olhada nelas também.

[]'s

Consultor SAC ACBr

Elton
Profissionalize o ACBr na sua empresa, conheça o ACBr Pro.

Projeto ACBr     Telefone:(15) 2105-0750 WhatsApp(15)99790-2976.

Um engenheiro de Controle de Qualidade(QA) entra num bar. Pede uma cerveja. Pede zero cervejas.
Pede 99999999 cervejas. Pede -1 cervejas. Pede um jacaré. Pede asdfdhklçkh.
Postado

Bom dia.

Realmente, "olhando por cima", tem mais alguns métodos na classes ACBrSintegra que precisa da mesma correção, sendo elas:

TRegistros75.Add

TRegistros75.Insert (Não testei)

TRegistros88Ean.Add (Não testei)

TRegistros88Ean.Insert (Não testei)

Atenciosamente.

Jéter Rabelo Ferreira

------------------------------------------------

Jéter Rabelo Ferreira
Campestre/MG

Postado

Bom dia.

Realmente, "olhando por cima", tem mais alguns métodos na classes ACBrSintegra que precisa da mesma correção, sendo elas:

TRegistros75.Add

TRegistros75.Insert (Não testei)

TRegistros88Ean.Add (Não testei)

TRegistros88Ean.Insert (Não testei)

Atenciosamente.

Jéter Rabelo Ferreira

Olá, não conheço o fonte componente ACBrSintegra, faça o teste ai vc, corrige, e após os teste funcionar, anexe que eu subo para o SVN.

Abraço

--
Isaque Pinheiro
Aracruz/ES - Brasil
___________________________________________________________________________
Site Oficial: www.isaquepinheiro.com.br 
Youtube: youtube.com/isaquepinheirooficialbr
Facebook: facebook.com.br/isaquepinheirooficialbr
Instagram: instagram.com/isaquepinheirooficialbr
Linkdin: https://www.linkedin.com/in/isaquepinheirooficialbr

Conheça o Projeto ORMBr Framework for Delphi - https://www.ormbr.com.br

 

Postado

Olá Isaque.

Uma parte ja está corrigida e a unit já foi anexada em meu primeiro post.

Caso deseje, pode mandar essa unit e, assim que eu terminar umas urgências, eu verifico o restante e te envio para que seja enviado ao svn.

Atenciosamente.

Jéter Rabelo Ferreira

------------------------------------------------

Jéter Rabelo Ferreira
Campestre/MG

  • 3 semanas depois ...
  • Membros Pro
Postado

Jeter,

Vc está correto... Obrigado pelo alerta.. já corrigi, e em breve envio para o SVN

Blz Daniel, só hoje sobrou um tempo pra dar uma olhada no ACBrSintegra, se precisar me avise que corrijo por aqui.

Ederson Selvati

Ederson Selvati
www.criareti.com.br

Skype: eselvati

  • Fundadores
Postado

o ACBrSintegra está bem estável... quase não precisa mais de atualizações :)

Esse problema do Memory Leak nunca reparei, pois fazíamos nossa própria verificação de existencia do Reg. 75 antes de cria-lo...

Consultor SAC ACBr

Daniel Simões de Almeida
O melhor TEF, é com o Projeto ACBr - Clique e Conheça
Ajude o Projeto ACBr crescer - Assine o SAC

Projeto ACBr     Telefone:(15) 2105-0750 WhatsApp(15)99790-2976.

  • 2 meses depois ...
Postado

Olá estou utilizando o ACBrSintegra em um projeto e detectei alguns memory leaks nos registros 60A, 60D, 60I..

Um bloco de memória vazou. O tamanho é: 116

Este bloco foi alocado pela thread 0x5C0, e a análise da pilha interna (endereços de retorno) no momento era:

40AA1E [..\..\biblioteca\rede unifar\FastMM4.pas][FastMM4][DebugReallocMem][6990]

402A8F [System][@ReallocMem]

423CB0 [Classes][TList.SetCapacity]

423AE8 [Classes][TList.Grow]

4238F9 [Classes][TList.Add]

442FB9 [Contnrs][TObjectList.Add]

5AFF20 [ACBrSintegra.pas][ACBrSintegra][TRegistros60D.Add][3030]

5A96D4 [ACBrSintegra.pas][ACBrSintegra][TACBrSintegra.GerarConjuntoRegistros60][1579]

5A938B [ACBrSintegra.pas][ACBrSintegra][TACBrSintegra.GeraArquivo][1507]

5B7ED0 [..\Model\UnitModelGerarArquivos.pas][UnitModelGerarArquivos][TModelGerarArquivos.GerarArquivo][114]

5B8294 [\\des03\Fontes\prjdelphi\ConthabWin\Model\dunit\UnitModelGerarArquivosTests.pas][UnitModelGerarArquivosTests][TModelGerarArquivosTests.TestGerarArquivo][70]


O bloco está sendo usado por um objeto da classe: Desconhecida

e o final do registro de log encontra-se assim
Essa aplicação teve vazamentos de memória. Os vazamentos dos blocos pequenos são (excluindo os vazamentos esperados registrados por ponteiro):


13 - 20 bytes: TObjectList x 3, TRegistros60D x 30, TRegistros60I x 30, TRegistros60A x 30, AnsiString x 1, Desconhecida x 3

21 - 36 bytes: TWinHelpViewer x 1, AnsiString x 2, Desconhecida x 3

37 - 52 bytes: THelpManager x 1, TStringList x 3, Desconhecida x 34

101 - 116 bytes: Desconhecida x 8

165 - 180 bytes: Desconhecida x 13

213 - 244 bytes: Desconhecida x 1

277 - 308 bytes: Desconhecida x 3

341 - 388 bytes: Desconhecida x 1


Nota: O detalhe do vazamento de memória está logado em um arquivo texto na mesma pasta que essa aplicação. Para desabilitar essa checagem de vazamento de memória, desabilite o DEFINE "EnableMemoryLeakReporting".

Analisando a linha de erro gerado pelo DUnit o problema está nas linha de codigo abaixo

procedure TACBrSintegra.GerarConjuntoRegistros60;

var

  i: Integer;

  wregistro60M: TRegistro60M;

begin

//associo todos os registros 60A/D/I criados a um registro 60M existente

//com esta abordagem permite-se que o usuario adicione registros fora

//de ordem na aplicacao cliente, ex: adiciona analitico primeiramente ao master.

//Com isto não há obrigacao de amarrar analitico ao master..deixando por conta do componente

//nao sei dizer se este processo de ordenacao efetuado pode tornar-se lento


if FVersaoValidador=vv524 then

begin

  //60A

  for i:=0 to Registros60A.Count - 1 do

  begin

    wregistro60M:=GetRegistro60M(Registros60A[i].Emissao,Registros60A[i].NumSerie);

    if not Assigned(wregistro60M) then

      raise Exception.Create(ACBrStr('Registro 60A sem registro 60M correspondente!'+#13+

        DateToStr(Registros60A[i].Emissao)+' - '+Registros60A[i].NumSerie));

    wregistro60M.Regs60A.Add(Registros60A[i]);

  end;


  //60D

  for i:=0 to Registros60D.Count - 1 do

  begin

    wregistro60M:=GetRegistro60M(Registros60D[i].Emissao,Registros60D[i].NumSerie);

    if not Assigned(wregistro60M) then

      raise Exception.Create(ACBrStr('Registro 60D sem registro 60M correspondente!'+#13+

        DateToStr(Registros60D[i].Emissao)+' - '+Registros60D[i].NumSerie));

    wregistro60M.Regs60D.Add(Registros60D[i]);

  end;


  //60I

  for i:=0 to Registros60I.Count - 1 do

  begin

    wregistro60M:=GetRegistro60M(Registros60I[i].Emissao,Registros60I[i].NumSerie);

    if not Assigned(wregistro60M) then

      raise Exception.Create(ACBrStr('Registro 60I sem registro 60M correspondente!'+#13+

        DateToStr(Registros60I[i].Emissao)+' - '+Registros60I[i].NumSerie));

    wregistro60M.Regs60I.Add(Registros60I[i]);

  end;


  //ordenando e gerando de acordo com o manual...

  Registros60M.Sort(Sort60M);

  for i:=0 to Registros60M.Count-1 do

  begin

    //removido pois sintegra tem ordem propria e nao consegui sortear os

    //objetos na lista de objetos com mais de um campo


    //    Registros60M[i].Regs60A.Sort(Sort60A);

    //    Registros60M[i].Regs60D.Sort(Sort60D);

    //    Registros60M[i].Regs60I.Sort(Sort60I);


    GerarRegistros60M(Registros60M[i]);

    GerarRegistros60A(Registros60M[i].Regs60A);

    GerarRegistros60D(Registros60M[i].Regs60D);

    GerarRegistros60I(Registros60M[i].Regs60I);

  end;

end

Gostaria de uma resolução para este problema, pois já tentei de todas as formas e não obtive sucesso.

Postado

Olá a todos já que niguém me respondeu a questão do memory leak no AcbrSintegra referente ao post anterior quero dizer que já encontrei a solução para o problema e gostaria que fosse corrigido no SVN para quando eu fizer um update do repositório não perdesse a minha codificação.

Bom a solução e bastante simples e somente iremos alterar a classe TRegistro60M no seu metodo create que está conforme mostrado abaixo:


constructor TRegistro60M.Create;

begin

  inherited Create;

  FRegs60A:=TRegistros60A.Create(True);

  FRegs60D:=TRegistros60D.Create(True);

  FRegs60I:=TRegistros60I.Create(True);

end;


iremos alterar e colocar um false para criar as listas sem ser Owner para que a responsabilidade de destruir a lista fique por nossa conta abaixo segue o codigo corrigido.

constructor TRegistro60M.Create;

begin

  inherited Create;

  FRegs60A:=TRegistros60A.Create(False);

  FRegs60D:=TRegistros60D.Create(False);

  FRegs60I:=TRegistros60I.Create(False);

end;

agora no método destrutor da classe TRegistro60M iremos destruir as listas referentes aos registros 60A, 60I e 60D conforme codificação abaixo:

destructor TRegistro60M.Destroy;

begin

  FreeAndNil(FRegs60A);

  FreeAndNil(FRegs60D);

  FreeAndNil(FRegs60I);

  inherited;

end;

Feito isso não existirá mais leaks de memória para esse registos.

Espero ter ajudado e qualquer dúvida entre em contato.

  • 2 semanas depois ...
  • Membros Pro
Postado

Olá a todos já que niguém me respondeu a questão do memory leak no AcbrSintegra referente ao post anterior quero dizer que já encontrei a solução para o problema e gostaria que fosse corrigido no SVN para quando eu fizer um update do repositório não perdesse a minha codificação.

Bom a solução e bastante simples e somente iremos alterar a classe TRegistro60M no seu metodo create que está conforme mostrado abaixo:


constructor TRegistro60M.Create;

begin

  inherited Create;

  FRegs60A:=TRegistros60A.Create(True);

  FRegs60D:=TRegistros60D.Create(True);

  FRegs60I:=TRegistros60I.Create(True);

end;


iremos alterar e colocar um false para criar as listas sem ser Owner para que a responsabilidade de destruir a lista fique por nossa conta abaixo segue o codigo corrigido.

constructor TRegistro60M.Create;

begin

  inherited Create;

  FRegs60A:=TRegistros60A.Create(False);

  FRegs60D:=TRegistros60D.Create(False);

  FRegs60I:=TRegistros60I.Create(False);

end;

agora no método destrutor da classe TRegistro60M iremos destruir as listas referentes aos registros 60A, 60I e 60D conforme codificação abaixo:

destructor TRegistro60M.Destroy;

begin

  FreeAndNil(FRegs60A);

  FreeAndNil(FRegs60D);

  FreeAndNil(FRegs60I);

  inherited;

end;

Feito isso não existirá mais leaks de memória para esse registos.

Espero ter ajudado e qualquer dúvida entre em contato.

Anizair

Obrigado pela correção, irei disponibilizar no SVN

Ederson Selvati
www.criareti.com.br

Skype: eselvati

  • Fundadores
Postado

Acho que a alteração não está completamente correta...

O Create dos ObjectLists deve usar True no parâmetro de criação:


constructor TRegistro60M.Create;
begin
inherited Create;
FRegs60A:=TRegistros60A.Create(True);
FRegs60D:=TRegistros60D.Create(True);
FRegs60I:=TRegistros60I.Create(True);
end;
[/code]

Como True, os Objetos inseridos dentro desses ObjectLists serão destruídos quando ele o for...

Ou seja.. com False, a chamada de: FreeAndNil(FRegs60D); não irá destruir os Objetos dentro de: FRegs60D

Consultor SAC ACBr

Daniel Simões de Almeida
O melhor TEF, é com o Projeto ACBr - Clique e Conheça
Ajude o Projeto ACBr crescer - Assine o SAC

Projeto ACBr     Telefone:(15) 2105-0750 WhatsApp(15)99790-2976.

Postado

Olá Daniel Simões,

Em Testes feito com o DUnit e o FastMM ocorreu o seguinte problema.

Quando estava setado true nas Lista internas do Objeto TRegistro60M não estava sendo liberado os objetos internos ou seja ficando os ObjectList interno sem ser liberado.

Ex : tinha 30 Registro60M e ficavam 30 Registro60A, 30 Registro60D, e 30 Registro60I.

Quando eu fiz o procedimento de correção citado no post o fastMM não mas acusou estes registros como leaks de memoria.

ou seja, significa que foram todos liberados.

vou voltar o codigo original fazer um teste com o fastMM e postar os logs aqui.

Analise os logs, e se achar alguma outra correção favor postar aqui.

ConthabWinTests_MemoryManager_EventosLog.txt

ConthabWinTests_MemoryManager_EventosLog.txt

Postado

Esqueci de mensionar, mas temos que lembrar que os registros Internos não são criados e sim somente referenciados, com isso não precisamos nos preocupar com o Free de cada registro, pois o objeto principal já se responsabiliza por isso.

Ex: Criarmos os TRegistro60A e adicionamos ao Componente no TRegistros60A e assim com os outros..

Internamente no componente é capturado a referencia do Registro60A e adicionado ao Registro60M.

Então ao destruir os registros60A do componente AcbrSintegra automaticamente será liberado do Registro60M por ser uma referencia, então devemos somente liberar os Registros internos do Registro60M.

  • Este tópico foi criado há 4860 dias atrás.
  • Talvez seja melhor você criar um NOVO TÓPICO do que postar uma resposta aqui.

Crie uma conta ou entre para comentar

Você precisar ser um membro para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar Agora
×
×
  • Criar Novo...

Informação Importante

Colocamos cookies em seu dispositivo para ajudar a tornar este site melhor. Você pode ajustar suas configurações de cookies, caso contrário, assumiremos que você está bem para continuar.