Estou com um problema de memory leak no meu datasnap, tenho esta rotina abaixo que eu recebo uma pacote TJSONArray, converto ele em TJSONObject, ambos os objetos que crio ele e não os destruo, porem eles estão ficando na memoria.
Li muito sobre isso, já fiz alguns cursos e todos sempre falam que o delphi vai remover eles depois, porem ao executar esta rotina em certa de 80 vezes, o datasnap fico com um consumo de memoria de quase 4Gb, ai ele da erro ou para de responder.
Se eu tento dar um free nos objetos, quando removo o primeiro da memoria ao remover o segundo, vem um erro do delphi falando sobre o ponteiro da classe TJSon, já tentei trocar a ordem dos free deste dois objetos e sempre da o mesmo erro.
Veja o meu Código:
function TServerMethods1.updateSetUsuarios(Cadastro: TJSONArray): String;
var vTabelaItens : TJSONObject;
vTransformeCampos, vCamposTabela : TJSONPair;
vRegistrosTabela : TJSONArray;
vTabelaDados : String;
I, R : Integer;
Q : TSQLQuery;
Transacao: TDBXTransaction;
begin
with DtCadastro do begin
vTabelaDados:= '{"result":'+Cadastro.ToString+'}';
vTabelaDados:= StringReplace(vTabelaDados,'[[','[',[]);
vTabelaDados:= StringReplace(vTabelaDados,']]',']',[]);
vTabelaItens:= TJSONObject.ParseJSONValue(TEncoding.ASCII.GetBytes(vTabelaDados),0) as TJSONObject;
vTransformeCampos:= TJSONPair.Create;
vTransformeCampos:= vTabelaItens.Get(0);
vRegistrosTabela:= TJSONArray.Create;
vRegistrosTabela:= (vTransformeCampos.JsonValue as TJSONArray);
vTabelaItens:= (vRegistrosTabela.Get(0) as TJSONObject);
Q:= TSQLQuery.Create(nil);
Q.SQLConnection:= GetConnectionByteAdmin;
try
try
Transacao:= Q.SQLConnection.BeginTransaction(TDBXIsolations.ReadCommitted);
for I := 0 to vRegistrosTabela.Size -1 do begin
R:= 0;
vTabelaItens:= (vRegistrosTabela.Get(I) as TJSONObject);
vCamposTabela:= vTabelaItens.Get(R);
Inc(R);
//Insert ou Update
if (vCamposTabela.JsonValue.Value = 'INSERT')
or (vCamposTabela.JsonValue.Value = 'UPDATE') then begin
Q.Close;
Q.SQL.Clear;
Q.SQL.Add(
'UPDATE OR INSERT INTO USUARIOS (CHAVE, COD_FILIAL, COD_USUARIO, NOME, SENHA, ATIVO) '+
'VALUES (:CHAVE, :COD_FILIAL, :COD_USUARIO, :NOME, :SENHA, :ATIVO) '+
'MATCHING (CHAVE, COD_USUARIO)');
vCamposTabela:= vTabelaItens.Get(R);
Inc(R);
Q.Params.ParamByName('CHAVE').AsString:= DefaultStr(vCamposTabela.JsonValue.Value,100);
vCamposTabela:= vTabelaItens.Get(R);
Inc(R);
Q.Params.ParamByName('COD_FILIAL').AsInteger:= DefaultInt(vCamposTabela.JsonValue.Value);
vCamposTabela:= vTabelaItens.Get(R);
Inc(R);
Q.Params.ParamByName('COD_USUARIO').AsInteger:= DefaultInt(vCamposTabela.JsonValue.Value);
vCamposTabela:= vTabelaItens.Get(R);
Inc(R);
Q.Params.ParamByName('NOME').AsString:= DefaultStr(vCamposTabela.JsonValue.Value,50);
vCamposTabela:= vTabelaItens.Get(R);
Inc(R);
Q.Params.ParamByName('SENHA').AsString:= DefaultStr(vCamposTabela.JsonValue.Value,20);
vCamposTabela:= vTabelaItens.Get(R);
Inc(R);
Q.Params.ParamByName('ATIVO').AsString:= DefaultTF(vCamposTabela.JsonValue.Value);
Q.ExecSQL;
end;
//Delete
if (vCamposTabela.JsonValue.Value = 'DELETE') then begin
Q.Close;
Q.SQL.Clear;
{CHAVE, COD_FILIAL, COD_USUARIO, NOME, SENHA, ATIVO}
Q.SQL.Add('DELETE FROM USUARIOS WHERE CHAVE =:CHAVE AND COD_USUARIO =:COD_USUARIO ');
vCamposTabela:= vTabelaItens.Get(R);
Inc(R);
Q.Params.ParamByName('CHAVE').AsString:= DefaultStr(vCamposTabela.JsonValue.Value,100);
vCamposTabela:= vTabelaItens.Get(R);
Inc(R);
Q.Params.ParamByName('COD_USUARIO').AsInteger:= DefaultInt(vCamposTabela.JsonValue.Value);
Q.ExecSQL;
end;
end;
Q.SQLConnection.CommitFreeAndNil(Transacao);
Result:= 'ok';
except
On E: Exception do begin
If Q.SQLConnection.InTransaction then
Q.SQLConnection.RollbackFreeAndNil(Transacao);
Result:= 'Erro';
end;
end;
finally
if (Q.SQLConnection.InTransaction) then
Q.SQLConnection.RollbackIncompleteFreeAndNil(Transacao);
DtCadastro.FreeConnection(Q.SQLConnection);
Q.Free;
end;
end;
end;
Algum já passou por isso antes, sabe me disse o que estou fazendo de errado:
Desde já agradeço a quem me ajudar!
Pergunta
guelf566@hotmail.com
Olá pessoal!
Estou com um problema de memory leak no meu datasnap, tenho esta rotina abaixo que eu recebo uma pacote TJSONArray, converto ele em TJSONObject, ambos os objetos que crio ele e não os destruo, porem eles estão ficando na memoria.
Li muito sobre isso, já fiz alguns cursos e todos sempre falam que o delphi vai remover eles depois, porem ao executar esta rotina em certa de 80 vezes, o datasnap fico com um consumo de memoria de quase 4Gb, ai ele da erro ou para de responder.
Se eu tento dar um free nos objetos, quando removo o primeiro da memoria ao remover o segundo, vem um erro do delphi falando sobre o ponteiro da classe TJSon, já tentei trocar a ordem dos free deste dois objetos e sempre da o mesmo erro.
Veja o meu Código:
function TServerMethods1.updateSetUsuarios(Cadastro: TJSONArray): String;
var vTabelaItens : TJSONObject;
vTransformeCampos, vCamposTabela : TJSONPair;
vRegistrosTabela : TJSONArray;
vTabelaDados : String;
I, R : Integer;
Q : TSQLQuery;
Transacao: TDBXTransaction;
begin
with DtCadastro do begin
vTabelaDados:= '{"result":'+Cadastro.ToString+'}';
vTabelaDados:= StringReplace(vTabelaDados,'[[','[',[]);
vTabelaDados:= StringReplace(vTabelaDados,']]',']',[]);
vTabelaItens:= TJSONObject.ParseJSONValue(TEncoding.ASCII.GetBytes(vTabelaDados),0) as TJSONObject;
vTransformeCampos:= TJSONPair.Create;
vTransformeCampos:= vTabelaItens.Get(0);
vRegistrosTabela:= TJSONArray.Create;
vRegistrosTabela:= (vTransformeCampos.JsonValue as TJSONArray);
vTabelaItens:= (vRegistrosTabela.Get(0) as TJSONObject);
Q:= TSQLQuery.Create(nil);
Q.SQLConnection:= GetConnectionByteAdmin;
try
try
Transacao:= Q.SQLConnection.BeginTransaction(TDBXIsolations.ReadCommitted);
for I := 0 to vRegistrosTabela.Size -1 do begin
R:= 0;
vTabelaItens:= (vRegistrosTabela.Get(I) as TJSONObject);
vCamposTabela:= vTabelaItens.Get(R);
Inc(R);
//Insert ou Update
if (vCamposTabela.JsonValue.Value = 'INSERT')
or (vCamposTabela.JsonValue.Value = 'UPDATE') then begin
Q.Close;
Q.SQL.Clear;
Q.SQL.Add(
'UPDATE OR INSERT INTO USUARIOS (CHAVE, COD_FILIAL, COD_USUARIO, NOME, SENHA, ATIVO) '+
'VALUES (:CHAVE, :COD_FILIAL, :COD_USUARIO, :NOME, :SENHA, :ATIVO) '+
'MATCHING (CHAVE, COD_USUARIO)');
vCamposTabela:= vTabelaItens.Get(R);
Inc(R);
Q.Params.ParamByName('CHAVE').AsString:= DefaultStr(vCamposTabela.JsonValue.Value,100);
vCamposTabela:= vTabelaItens.Get(R);
Inc(R);
Q.Params.ParamByName('COD_FILIAL').AsInteger:= DefaultInt(vCamposTabela.JsonValue.Value);
vCamposTabela:= vTabelaItens.Get(R);
Inc(R);
Q.Params.ParamByName('COD_USUARIO').AsInteger:= DefaultInt(vCamposTabela.JsonValue.Value);
vCamposTabela:= vTabelaItens.Get(R);
Inc(R);
Q.Params.ParamByName('NOME').AsString:= DefaultStr(vCamposTabela.JsonValue.Value,50);
vCamposTabela:= vTabelaItens.Get(R);
Inc(R);
Q.Params.ParamByName('SENHA').AsString:= DefaultStr(vCamposTabela.JsonValue.Value,20);
vCamposTabela:= vTabelaItens.Get(R);
Inc(R);
Q.Params.ParamByName('ATIVO').AsString:= DefaultTF(vCamposTabela.JsonValue.Value);
Q.ExecSQL;
end;
//Delete
if (vCamposTabela.JsonValue.Value = 'DELETE') then begin
Q.Close;
Q.SQL.Clear;
{CHAVE, COD_FILIAL, COD_USUARIO, NOME, SENHA, ATIVO}
Q.SQL.Add('DELETE FROM USUARIOS WHERE CHAVE =:CHAVE AND COD_USUARIO =:COD_USUARIO ');
vCamposTabela:= vTabelaItens.Get(R);
Inc(R);
Q.Params.ParamByName('CHAVE').AsString:= DefaultStr(vCamposTabela.JsonValue.Value,100);
vCamposTabela:= vTabelaItens.Get(R);
Inc(R);
Q.Params.ParamByName('COD_USUARIO').AsInteger:= DefaultInt(vCamposTabela.JsonValue.Value);
Q.ExecSQL;
end;
end;
Q.SQLConnection.CommitFreeAndNil(Transacao);
Result:= 'ok';
except
On E: Exception do begin
If Q.SQLConnection.InTransaction then
Q.SQLConnection.RollbackFreeAndNil(Transacao);
Result:= 'Erro';
end;
end;
finally
if (Q.SQLConnection.InTransaction) then
Q.SQLConnection.RollbackIncompleteFreeAndNil(Transacao);
DtCadastro.FreeConnection(Q.SQLConnection);
Q.Free;
end;
end;
end;
Algum já passou por isso antes, sabe me disse o que estou fazendo de errado:
Desde já agradeço a quem me ajudar!
Link para o comentário
Compartilhar em outros sites
1 resposta a esta questão
Posts Recomendados
Participe da discussão
Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.