Aşağıdaki basit bir procedure 'de oluşan bir memoryLeak vardı ayda binlerce kez çalıştığı için memoryleak'ten şişmemesi için dikkat etmek gerekiyor..
Şimdi aşağıdaki kodu incelersek , her hangi bir memoryLeak'e fırsat vermediğimi görebilrsiniz.
Olmaz ya oldu herhangi bir sebebten dolayı bu kod çalışmadı
Yorum satırı haline aldım
Normal şartlarda Create olmadığı için AddPair yapamayacak AV hatası fırlatacak, sonrasında finallye düştüğü için tüm objeler free olacak hafızam boşalacak.
Ancak boşalmıyor bu hata fırlıyor.
Ben sorunu buldum önlemini aldım, Birazdan paylaşacağım ama öncelikle sizden duyayım, Bu memroyleak sizce neden oluştu ?
Cevap,
AddPair fonksiyonu , kendi nil olsa dahi içeride bir JsonPair Create Ediyor ancak Result := self dediğinde self yani kendisi henüz create olmadığı için atama yapılırken erişmek isteyince AV oluşuyor.
Şimdi aşağıdaki kodu incelersek , her hangi bir memoryLeak'e fırsat vermediğimi görebilrsiniz.
var JSONField: TJSONObject; JArray: TJSONArray; i: Integer; Conn: TMyConnection; Query: TMyQuery; inSql: String; begin if ConnectionString = '' then Exit; Conn := TMyConnection.Create(nil); Conn.ConnectString := ConnectionString; Conn.Connect; Query := TMyQuery.Create(nil); Query.Connection := Conn; JArray := TJSONArray.Create; try try Query.Close; Query.Sql.Clear; inSql := ifthen(Trim(ModelYil) = EmptyStr, EmptyStr, 'WHERE yil="' + ModelYil + '"'); Query.Sql.Add('SELECT mkod,marka FROM aracdeger ' + inSql + ' GROUP BY mkod ORDER BY marka'); Query.Open; if not Query.IsEmpty then begin while not Query.Eof do begin JSONField := TJSONObject.Create; for i := 0 to Query.FieldCount - 1 do JSONField.AddPair(Query.Fields[i].FieldName, Query.FieldByName(Query.Fields[i].FieldName).AsString.Replace('\', '/')); JArray.AddElement(JSONField); Query.Next; end; end else JArray.Add('İstenen Liste Boş'); except on E: Exception do JArray.Add(E.Message); end; finally Result := JArray.ToString; if Assigned(JArray) then JArray.Free; if Assigned(Query) then FreeAndNil(Query); if Assigned(Conn) then FreeAndNil(Conn); end; end;
Olmaz ya oldu herhangi bir sebebten dolayı bu kod çalışmadı
JSONField := TJSONObject.Create;
Yorum satırı haline aldım
// JSONField := TJSONObject.Create; for i := 0 to Query.FieldCount - 1 do JSONField.AddPair(Query.Fields[i].FieldName, Query.FieldByName(Query.Fields[i].FieldName).AsString.Replace('\', '/')); JArray.AddElement(JSONField);
Normal şartlarda Create olmadığı için AddPair yapamayacak AV hatası fırlatacak, sonrasında finallye düştüğü için tüm objeler free olacak hafızam boşalacak.
Ancak boşalmıyor bu hata fırlıyor.
Ben sorunu buldum önlemini aldım, Birazdan paylaşacağım ama öncelikle sizden duyayım, Bu memroyleak sizce neden oluştu ?
Cevap,
AddPair fonksiyonu , kendi nil olsa dahi içeride bir JsonPair Create Ediyor ancak Result := self dediğinde self yani kendisi henüz create olmadığı için atama yapılırken erişmek isteyince AV oluşuyor.
function TJSONObject.AddPair(const Str: string; const Val: string): TJSONObject; begin if (not Str.IsEmpty) then AddPair(TJSONPair.Create(Str, Val)); Result := Self; end;