2014-12-09 6 views
1

Delphi Xe5와 함께 idHTTPserver를 사용하여 중소 기업 환경에서 REST API 서비스를 로컬로 제공하려고합니다. 클라이언트에 파일을 보내기 전에 파일을 처리하기 전에이 시점에서 문제가 발생합니다. 메모리는 프로세스가 완료된 후에 해제되지 않습니다.
생성 된 JSON 객체가 클라이언트에게 올바르게 전송되었습니다. (AngularJS App)TJSONObject 복잡한 json 개체 누수 개체

내가 뭘 잘못하고 있니? 나는 HTTP 클라이언트 요청을 수신 할 때

나는 당신은 결코 TORDEN 변수, 따라서 메모리 누수를 해제하지 않습니다

Procedure TMain.IdHTTPServer1CommandGet(AContext: TIdContext; 
ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo); 
Var 
    // Here Var Types 

    Json,LFilename:String; 
    ROOTCOMANDAS,TORDEN,DATA,MSG : TJSONObject; 
    Dlnew,d : TJSONArray 
    files:tfilestream; 

Begin 

LFilename := ARequestInfo.Document; 

if AnsiSameText(LFilename, '/resto/orders/jsondata') then 
begin 
    files := TFileStream.Create('htd' + LFilename, fmOpenRead + fmShareDenyWrite); 
    Json := ReadStringFromStream(files); 
    files.Free; 
    ROOTCOMANDAS := TJSONOBJECT.ParseJSONValue(TEncoding.ASCII.GetBytes(Json), 0) as TJSONOBJECT; 
    try 
    Data := ROOTCOMANDAS.Get('data').JSONValue as TJSONOBJECT; 
    d := Data.Get('d').JSONValue as TJSONArray; 
    dlnew := TJSONArray.Create; 

    for LValue in d do 
     if (LValue as TJSONOBJECT).GetValue('ss').Value = '0' then 
     dlnew.AddElement(LValue); 

    TORDEN := TJSONOBJECT.Create; 

    Msg := TJSONOBJECT.Create; 
    Msg.AddPair(TJSONPair.Create('t', TJSONString.Create('m5000_325'))); 
    Msg.AddPair(TJSONPair.Create('tipo', TJSONNumber.Create(5))); 

    TORDEN.AddPair(TJSONPair.Create('msg', Msg)); 

    Msg := TJSONOBJECT.Create; 

    Msg.AddPair(TJSONPair.Create('et', TJSONString.Create(ETAGL))); 
    Msg.AddPair(TJSONPair.Create('d', dlnew)); 

    TORDEN.AddPair(TJSONPair.Create('data', Msg)); 
    TORDEN.AddPair(TJSONPair.Create('ok', TJSONTrue.Create)); 
    TORDEN.AddPair(TJSONPair.Create('md', TJSONNumber.Create(iFD))); 
    TORDEN.AddPair(TJSONPair.Create('time', TJSONString.Create(UTC))); 

    Json := TORDEN.ToString; 

    AResponseInfo.CacheControl := 'no-cache'; 
    AResponseInfo.CustomHeaders.Values['Access-Control-Allow-Headers'] := 'Content-Type'; 
    AResponseInfo.CustomHeaders.Values['Access-Control-Allow-methods'] := 'GET,POST,OPTIONS'; 
    AResponseInfo.CustomHeaders.Values['Access-Control-Allow-origin'] := '*'; 
    AResponseInfo.CharSet := 'utf-8'; 
    AResponseInfo.Pragma := 'Public'; 
    AResponseInfo.Server := 'Drone'; 
    AResponseInfo.ContentText := Json; 
    finally 
    ROOTCOMANDAS.Free; 
    end; 

    exit; 
end; 
+1

지금까지 내가 당신이 TORDEN 변수를 해제하지 않는 볼 수 어디서나 –

+0

예 .. 때문에 내가 알고있는, 내가 오류 얻을 해당 개체를 해제하려고 할 때 ROOTCOMANDAS 또는 Root Object를 해제하면 모든 트리가 해제됩니다. im right no? – JavierDonosoV

+2

사용하는 변수의 유형을 표시하지 않는 이유는 무엇입니까? 그것은 차이를 만들 수 있습니다. 이 디버깅을 시도 했습니까? 전체 FastMM이 누출 된 것을 알려줍니다. 누수가 사라질 때까지 코드를 자르셨습니까? 이러한 기본적인 디버깅 기술을 익히는 것이 모두에게 도움이됩니다. –

답변

0

.. 이렇게, 당신은에 따라이 발생 해제하려고 할 때 당신이 얻을 오류 라인 :

for LValue in d do 
    if (LValue as TJSONOBJECT).GetValue('ss').Value = '0' then 
    dlnew.AddElement(LValue); 

LValued에 의해 소유되고 해제 될 때 d 발표 될 예정이다, 당신은 dlnewLValue를 추가하는 것입니다 또한 그것을 공개하고 싶습니다. 두 개체가 동일한 포함 된 개체를 소유하고 릴리스하기 때문에 여기에서 소유권 문제가 발생합니다.

문제를 해결하기 위해 변화를 다음보십시오 :

for LValue in d do 
    if (LValue as TJSONOBJECT).GetValue('ss').Value = '0' then 
    begin 
     dlnew.AddElement(LValue); 
     // here you are saying that you don't want to release object when ROOTCOMANDAS is released 
     LValue.Owned := false; 
    end; 
// release ROOTCOMANDAS and d along with it 
ROOTCOMANDAS.Free; 
// Set back owned property to true so you don't leak objects 
for LVaue in dlnew do 
    LValue.Owned := true; 
... 
    Json := TORDEN.ToString; 
    TORDEN.Free; 

... remove superfluous ROOTCOMANDAS.Free; in finally part 
+0

감사합니다 !! Dalija, 지금 일하고있는 것 같다. 나는 DBXJSON 라이브러리의 TJSON 객체에서 "소유 된"메소드의 사용을 알지 못했다. 고맙습니다 ... Javier. – JavierDonosoV