Ir para conteúdo
  • Cadastre-se

dev botao

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

Recommended Posts

  • Membros Pro
Postado

Boa Noite,

Amigos, estou abrindo este tópico para tratarmos de alguns dificuldades na migração de Delphi sem suporte a UNICODE, Nos aqui já migramos todas as nossas ferramentas para XE5, pois conseguimos todos os componentes de terceiros para esta versão. Tudo rodando 100%. Mais alguns pontos foram encontrados e conto com a ajuda de todos aqui do fórum, aproveito para parabenizar a todos os amigos, pois é assim que os vejo, profissionais amigos!

Eu particularmente sou muito preocupado com Memory Leak (Vazamento de Memoria) tento no máximo liberar todos os componentes criados em Run-Time, no BDS2006 plataforma aonde ficamos por anos com nossas ferramentas quase não tínhamos problemas com Memory Leak, até tinha, mais tratando de componentes de terceiro sem fonte.

Bem ao migramos para o XE5, trocamos apenas as chamadas de String para AnsiString que foram necessário (Fazendo uso de caracteres). Mais agora ao Degugar a aplicação ativando "Monitoramento de Memory Leak" Mostra vários pontos que não foram liberados e todos quase com referência a UnicodeString  

O que pode está acontecendo?

Isto poderá impactar em lentidão no sistema?

Print das telas em anexo.

Dica: Em todos os meus projetos eu acrescento no final do form principal esta linha, assim será levantado um relatório do que não foi liberado da memoria:

initialization
  ReportMemoryLeaksOnShutdown := DebugHook <> 0;

MemoryLeak01.jpg

MemoryLeak02.jpg

MemoryLeak03.jpg

Postado

@Duarte eu sempre migrei meu sistema para versões mais novas do Delphi, mas como nem tudo são flores, já passei pelo problema que vc está passando, recentemente na versão XE8 e Seattle, tive problemas de vazamento de memória da qual não me deixava migrar, e esses vazamento não eram de meus projetos, mas do próprio delphi.

"Unknown" quer dizer desconhecido, esses vazamento desconhecido, são do Delphi.

XE8 e Seattle mesmo tem vazamento na biblioteca DBX, o qual me fez migrar todo meu sistema para FireDAC, para que hoje eu tenho meus projeto nele.

Te aconselho 1o em tentar compilar seu sistema em um outra versão do Delphi, assim vai ter certeza que o vazamento é no seu sistema ou no delphi (pelo erro acredito que é do delphi), e no ACBr fique tranquilo, pois esse eu uso em massa no meus sistemas, e hj no Seattle não tem vazamento.

--
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

 

  • Membros Pro
Postado
51 minutos atrás, Isaque Pinheiro disse:

@Duarte eu sempre migrei meu sistema para versões mais novas do Delphi, mas como nem tudo são flores, já passei pelo problema que vc está passando, recentemente na versão XE8 e Seattle, tive problemas de vazamento de memória da qual não me deixava migrar, e esses vazamento não eram de meus projetos, mas do próprio delphi.

"Unknown" quer dizer desconhecido, esses vazamento desconhecido, são do Delphi.

XE8 e Seattle mesmo tem vazamento na biblioteca DBX, o qual me fez migrar todo meu sistema para FireDAC, para que hoje eu tenho meus projeto nele.

Te aconselho 1o em tentar compilar seu sistema em um outra versão do Delphi, assim vai ter certeza que o vazamento é no seu sistema ou no delphi (pelo erro acredito que é do delphi), e no ACBr fique tranquilo, pois esse eu uso em massa no meus sistemas, e hj no Seattle não tem vazamento.

Bom dia, Muito obrigado pela resposta, Não é erro no meus projetos não! Pois ele já tem mais de 9 anos, vim do delphi 6 para BDS2006 agora para XE5, deste a primeira versão do nosso sistema que tivemos muito cuidado com Memory Leaks. Estava pensando em ir para Seatla, mais como você já mencionou o problema om DBX, cara meu sistema usa tudo DBExpress Agora DBX, sendo assim seria um caus ter que mudar para FireDAC.

Sobre o ACBr, eu também uso quase 100% dele, realmente está rodando 100%...! Só estou migrando por causa do ACBr, não posso nunca nem sonhar em ficar sem esta biblioteca...!

Uma Pergunta, Você ao migrar para FireDAC, trocou os seus ClientDataSet, pois o FireDAC tem a mesma funcionalidade num só componente... Ou trocou apenas os TQuery? Deixando o mesmo ligamento (Query -> Provader -> ClientDaset -> DataSouce)? Pois se for para trocar para FireDAC teria que manter este vinculo. O FirecDAC se comporta bem nesta estrutura?

Postado

--
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

 

  • Membros Pro
Postado
47 minutos atrás, Duarte disse:

Bom dia, Muito obrigado pela resposta, Não é erro no meus projetos não! Pois ele já tem mais de 9 anos, vim do delphi 6 para BDS2006 agora para XE5, deste a primeira versão do nosso sistema que tivemos muito cuidado com Memory Leaks. Estava pensando em ir para Seatla, mais como você já mencionou o problema om DBX, cara meu sistema usa tudo DBExpress Agora DBX, sendo assim seria um caus ter que mudar para FireDAC.

Sobre o ACBr, eu também uso quase 100% dele, realmente está rodando 100%...! Só estou migrando por causa do ACBr, não posso nunca nem sonhar em ficar sem esta biblioteca...!

Uma Pergunta, Você ao migrar para FireDAC, trocou os seus ClientDataSet, pois o FireDAC tem a mesma funcionalidade num só componente... Ou trocou apenas os TQuery? Deixando o mesmo ligamento (Query -> Provader -> ClientDaset -> DataSouce)? Pois se for para trocar para FireDAC teria que manter este vinculo. O FirecDAC se comporta bem nesta estrutura?

Show de Bola Isaque, hoje todo o nosso sistema é TQuery + Provader + ClientDaset, irei seguir sua linha de raciocio, concordo 100% contigo... O Bom da FireDAC é como você disse mais banco podem ser acessado, inclusive Mysql que até então deveriamos usar outra Engine como Zeos creio que uma das mais usadas.

Voltando ao assunto do Memory Leaks, em pesquisa ouvi falar sobre "SCALYMM2" que promete remover este tipo de erros, conhece esta unit?

 

Postado

Não ouvi falar não, uso o do delphi que é basedado em FastMM4

--
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

 

  • Membros Pro
Postado
43 minutos atrás, Isaque Pinheiro disse:

Não ouvi falar não, uso o do delphi que é basedado em FastMM4

Boa tarde,

Quando você se refere ao usar o delphi está se referindo, desta linha que acrescentamos ao final do form principal?

initialization
  ReportMemoryLeaksOnShutdown := DebugHook <> 0;

Ai quando debugamos ao finalizar a aplicação ele mostra os objetos que não foram liberados?

Postado

Exato.

--
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

 

  • Membros Pro
Postado
4 horas atrás, Isaque Pinheiro disse:

Exato.

Boa noite,

É meu amigo, migrei para XE10, os erros de Memory Leaks com UnicodeString condinuam, sem saber de onde vem eles, mesmo usando o EukaLog não conseguir rastrear... Vou migrar agora o meu projeto para FireDAC e largar de mão o DBX. Vamos ver...

  • Membros Pro
Postado (editado)

Bom dia,

Bem, migrei para XE10 Seatla, os Memory Leaks continuaram, peguei a dica apontado pelo nosso amigo Isaque Pinheiro. Fiz um teste, acrescentei apenas um TSQLConnetion + TSimpleDaset, este consultado uma tabela com 75 campos com variados tipos de dados. veja o tanto de Memory Leaks levantado... Print logo abaixo...

Bem, um amigo meu usa uma unit chamda ScaleMM2, ao acrescentar ela no dpr do projeto os memory leaks somem, alguém já usa esta unit. Sabe me dizer o que ela realmente propoem e se consegue? Ou seja tem como testar se ela libera ou apenas omite os aviso de Memory Leaks?

MemoryLeaks.png

Editado por Duarte
  • Membros Pro
Postado
Em 22/02/2016 at 14:28, Isaque Pinheiro disse:

Exato.

Boa tarde,

Isaque, inicie o processo de migração de DBX para FireDAC, e já me deparei com algo que me esquentou a cabeça, veja se você passou por isto...

Cenário Hoje aqui: Uso FireBird 2.5 para campos númerico uso: Numeric = Size = 15 Scale = 2/3. Bem na DBX este campos eram retornados como: TFMTBCDField agora pela FireDAC eles estão vindo como: TBCDField. Ou seja, terei que apagar e chama-los novamente nos ClientDaset, pode até falar simples, nem tanto... Tenho DataModule com centenas de ClientDaset e utilizo muito os eventos (OnValidate, OnChange, OnGetText) Sem falar que bolei um técnica que uso a propriedade do Campo "Origem" para setar de onde vem os dados no caso dele vim de campo dinamico de deu um LEFT JOIN que só é retornado ao atualizar a tabela, se eu apagar e adiciona-los terei que redefinir tudo... Tem como Setar para FireDAC retornar os campos números como TFMTBCDField?

Postado

Boa tarde @Duarte não me deparei com esse problema, no meu sistema desenvolvi uma tecnologia para usar multi-banco, e nessa tecnologia não uso TFilelds em tempo de designer.
TFields, Todos os eventos, crio tudo em code.

Não tem como, quem define o tipo é o delphi dependendo do engine e do banco usado, por isso aboli TFileds em tempo de designer.

--
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

 

  • Membros Pro
Postado
3 horas atrás, Isaque Pinheiro disse:

Boa tarde @Duarte não me deparei com esse problema, no meu sistema desenvolvi uma tecnologia para usar multi-banco, e nessa tecnologia não uso TFilelds em tempo de designer.
TFields, Todos os eventos, crio tudo em code.

Não tem como, quem define o tipo é o delphi dependendo do engine e do banco usado, por isso aboli TFileds em tempo de designer.

Boa noite,

Quero aqui reportar com muito prazer que é possível tratar o erro que encontrei acima usando o próprio FireDAC, por sinal estou ficando apaixonado por esta Engine de acesso... RSRS Veja como tratar qualquer tipo de dados com FireDAC...

 

1º Na sua FDConnection1 encontre a seguinte propriedade: TFDFormatOptions->TFDMapRules (Nesta propriedade é possível fazer um mapeamento dos tipos de dados, isto mesmo, você determinar que tipo será entrada e que será a saída)... No meu caso ficou assim:

 

 

MapearTipoFireDAC.png

  • Curtir 4
  • Membros Pro
Postado

Boa noite,

Complementando o post que fiz acima, notei que em alguns casos os MapeRoles são removidos, não sei explicar o porque, mais resolvi o problema acrescentando os MapeRoles em run-time assim:  Coloquei depois de conectar...

procedure T_dmDados._ConexaoAfterConnect(Sender: TObject);
begin
  _Conexao.FormatOptions.MapRules.Clear;
  with _Conexao.FormatOptions.MapRules.Add do
  begin
    SourceDataType := dtBCD; //Tipo de entrada.
    TargetDataType := dtFmtBCD; // Tipo de Saída.
  end;
end;

  • Curtir 3
Postado

Show de bola, havia me esquecido desse recurso, ele já existia desde AnyDAC (agora FireDAC) quando a Embarcadero comprou, a finalidade é justamente proporcionar o desenvolvimento multi-bancos.

Parabéns pela migração, agora você está em outro mundo de recursos.

  • Curtir 1

--
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

 

  • Membros Pro
Postado
6 minutos atrás, renato_oda disse:

@Duarte só para complementar (uma dica) vi que está migrando para FireDac, a Embarcadero oferece um reFind bacana que utilizei nessa migração.

http://docwiki.embarcadero.com/RADStudio/XE8/en/DbExpress_Application_Migration_(FireDAC)

Boa sorte!!!

Muito obrigado... Eu preferi fazer o trabalho na mão, pois tem muita coisa que preciso analisar, O nosso sistema está bem instável, quero fazer está migração, mais manter a mesma qualidade, ou melhor, melhorar a qualidade, uma migração de forma "Automatizada" poderia criar muitos pontos negativos que passariam desapercebido, exemplo de um deles no meu caso:

* Usei um técnica minha aqui para alimentar campos oriundos de sub-consulta SQL tipo (LEF JOINT, INNER JOINT) que só são atualizadas no refresh da tabela, mais nem sempre dar para dar um refresh, ai eu uso uma função minha mesmo, para tal uso a propriedade do ClientDaset "ORIGIN", com a DBX este campo não era alimentado, sempre vinha limpo, agora com FireDAC ele com o mesmo nome do FieldName, e ao ativar o ClientDataSet o Provider repassa este valor é nome caso esta assim. Ex. ID_CLIENTE=RAZAO (Onde ID_CLIENTE é o campo que tem a função no onChange e na "ORIGIN" deste tem o ClientDaset onde ele vai pesquisar. 

Em fim... Acho que terá que ser na unha mesmo... rsrs, mais deste já agradeço e vou dar uma olhada nesta dica com certeza.

Postado

Irá chegar ao final sem nenhum Memory Leaks com certeza, esse problema já vem desde a versão XE8 o qual já relatei para a Embarcadero desde essa versão, saiu a XE10 e não resolveram, saiu UPD1 do XE10 e nada ainda.

Relatei o problema a QC Embarcadero no dia 12/09/2015.

--
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

 

  • Membros Pro
Postado (editado)
2 horas atrás, Isaque Pinheiro disse:

Irá chegar ao final sem nenhum Memory Leaks com certeza, esse problema já vem desde a versão XE8 o qual já relatei para a Embarcadero desde essa versão, saiu a XE10 e não resolveram, saiu UPD1 do XE10 e nada ainda.

Relatei o problema a QC Embarcadero no dia 12/09/2015.

Boa noite,

Isaque você que já esta mais familiarizado com FireDAC, será que poderia me ajudar neste caso:

Tenho num banco exclusivo par armazenar fotos (Clientes, Produtos, Funcionários, etc), nele é armazenado a ID e Foto campo Blob, Para gravar no banco faço assim:

Foto := TJpegImage.Create;
Foto.LoadFromFile(_opdImagem.FileName);
clipboard.Assign(Foto);
_dbiFoto.PasteFromClipboard;

Ai link o campo TBlobField ao TDBImage... Pronto aqui funciona a anos pelo DBX.

Mais no FireDAC os campos blob estão vindo como String, sabe como tratar este caso?

Editado por Duarte
Postado

Vc está usando TDataSetProvider ? Se tiver, qual o valor atribuído a propriedade Options->poFetchBlobsOnDemand ? Se tiver como false, tente mudar para True e faça o teste.

--
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

 

  • Membros Pro
Postado
6 minutos atrás, Isaque Pinheiro disse:

Vc está usando TDataSetProvider ? Se tiver, qual o valor atribuído a propriedade Options->poFetchBlobsOnDemand ? Se tiver como false, tente mudar para True e faça o teste.

Bom dia,

Sim, estou usando Provider, e está setado esta propriedade como True, no entanto e me retornado não um TBlobField mais sim um TStringField, pelo que notei o FireDAC agora trabalha com Stream, peguei um código da net, mais ainda não testei, vou testa-lo, segue exemplo:

Gravando a imagem no Banco de Dados:

procedure frmTeste.btnIncluirFotoClick(Sender: TObject);
var
  vArquivo: TFileStream;
begin
  vArquivo := TFileStream.Create('d:\01.bmp', fmOpenRead or fmShareDenyWrite);
  FDQuery1.Close;
  FDQuery1.SQL.Clear;
  //Pode ser feito Insert ou Update
  FDQuery1.SQL.Add('INSERT INTO tbl_usuario (FOTO) VALUES(:FOTOCARREGADA)');
  FDQuery1.Params[0].DataType := ftBlob;
  FDQuery1.ParamByName('FOTOCARREGADA').AsStream := vArquivo;
  FDQuery1.ExecSQL;
  FDQuery1.Close;
end;

Lendo a imagem do Banco de Dados:

procedure frmTeste.btnCarregarFotoClick(Sender: TObject);
var
  vFoto   : TStream;
  vImagem : TBitmap;
begin     
  FDQuery1.Close;
  FDQuery1.SQL.Add('SELECT * FROM tbl_usuario WHERE id_usuario = 6');
  FDQuery1.Open;

  //Lendo a imagem do campo BLOB para a Memória
  vFoto := FDQuery1.CreateBlobStream(FDQuery1.FieldByName('FOTO'), bmRead);

  //Criando a instância de TBitmap (pode ser JPG tb)
  vImagem := TBitmap.Create;

  //Carregando a imagem a partir do stream TStream
  vImagem.LoadFromStream(vFoto);

  //Exibindo a Imagem
  Image1.Picture.Assign(vImagem);
  //Image1.Bitmap.LoadFromStream(vFoto); //Caso esteja usando FMX ao invés de VCL
end;

Vou testar assim que terminar algo aqui, meu medo ai é, será que vai recuperar o que já está armazenado no banco? E lá está .JPG...

  • Membros Pro
Postado

Bom dia.

Graças ao meu Deus, terminei de migrar todos os projetos para XE10, trocamos todos os DBX por FireDAC, bem quase todos os Memory Leaks foram sanados, ainda ficaram alguns mais trata-se do DataSnap pois usamos muito conexões remotas com DataSnap e esta ainda usa DBX, eu pergunto para meus amigos, esta levantando muitos memory Leaks com JSON + DataSnap, pois uso assim:

* Tenho funções aonde no servidor é criados Classes e convertidas em JSONObject do lado do clientes retorno para classe.

* Tenho funções aonde no servidor faça consultas, monto .xml comprimo ele com zLib e transformo em JSON no cliente faço o processo reverso, deste modo é incrível a velocidade que importo dados remotamente, pois o meu sistema não suporta vários CNPJ no mesmo banco, porém faço toda a gestão de várias lojas num só .exe tudo com DataSnap + JSON...

Em fim, agora depois que migrei para XE10 tenho vários memory leaks, pois JSONArray não aceita Free/FreeAndNil.

Alguém ai está passando por isto?

  • Membros Pro
Postado (editado)
51 minutos atrás, Tiago Ravache disse:

Opa... O link em questão é apenas mostrando a estrutura do class, aponta para o Destructor Destroy, mais sem muitas explicações... Veja um parte de um dos código usado aqui:

 

var
  Dados: T_dmConexaoRemota;
  Debito: TDebito;
  Retorno : TClientDataSet;
begin
  try
    try
      Result := varNull;
      Dados := T_dmConexaoRemota.Create(nil);
      Dados._ConexaoServerNoturno.Params.Values['HostName'] := AHostName;
      Debito := JSONToDebito(Dados._MetodosServerNoturno.ConsultaDebitos(ATipo, ACNPJ)); //.ConsultaDebitos é JSONValue

finally
    if Assigned(Debito) then
      FreeAndNil(Debito);
    if Assigned(Retorno) then
      FreeAndNil(Retorno);
    Dados._ConexaoServerNoturno.Close;
    FreeAndNil(Dados);
  end;

Veja o retorno da função é um JSONValue, neste caso não tem como matar ele... Outro caso...

 

function ExportarDados(AEmpresa: String; ASQL: WideString;
  AArquivo : String) : OleVariant;
var
  Dados: T_dmConexaoRemota;
  Consulta: TJSONArray; 
//.Variavel usada para pegar o retorno do DataSnap que será um JSonArray
  Retorno: TClientDataSet;
  HostName: String;
begin
  try
    try
      Consulta := Dados._MetodosServerNoturno.ExportarDados(ASQL, AArquivo);
      if Assigned(Consulta) then
      begin
        AArquivo := JSONToFile(Consulta, PastaAplicacao + 'ConnectionRemote');

finally
    if Assigned(Retorno) then
      FreeAndNil(Retorno);
    Dados._ConexaoServerNoturno.Close;
    FreeAndNil(Consulta);
//.Se eu acrescentar esta linha, dar erro, pois não acessa liberar da memoria.
    DeleteFile(PWideChar(WideString(AArquivo)));
    AArquivo := SubstituirTexto(AArquivo, '.xml', '.zLib');
    DeleteFile(PWideChar(WideString(AArquivo)));
  end;

Editado por Duarte
  • Este tópico foi criado há 2150 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.