title: Delphi Marshalling my object to string leaks, but why?
body: <p>I wonder why the marshalling of my object to a string leaks, I've tried to free up the JSONMarshal (and in fact also tried to free the converter, by instantiating it) - but it still leaks? Shouldn't it be enough to free the JSONMarshal?</p>
  
  <pre><code>function TPerson.ToJsonString: string;
  var
    JSONMarshal: TJSONMarshal;
  begin
    result := '';
    JSONMarshal := TJSONMarshal.Create(TJSONConverter.Create);
    try
      Result := JSONMarshal.Marshal(self).ToString;
    finally
      JSONMarshal.Free;
    end;
  end;
  </code></pre>
  
  <p>Here's a test object - just make an instance of TPerson (1, ') and call the ToJsonString - then you'll see the leak.</p>
  
  <pre><code>unit TestObjU;
  
  interface
  
  uses
    Classes, System.Generics.Collections, System.SysUtils,
    Data.DBXJSON, Data.DBXJSONReflect, JSON,
    Data.FireDACJSONReflect, FireDAC.Comp.Client, vcl.ExtCtrls,
    pngimage, graphics, variants;
  
  type
    EPerson = class(Exception);
    EPersonsList = class(Exception);
  
    TGender = (Female, Male);
  
    TPerson = class(TObject)
    private
      FFirstName: string;
      FLastName: string;
      FId: Integer;
      FGender: TGender;
      FModified : Boolean;
      [JSONMarshalled(False)]
      FPicture : TPicture;
      function GetName: string;
      procedure SetFirstName(const Value: string);
      procedure SetLastName(const Value: string);
      function GetId: Integer;
      procedure SetGender(const Value: TGender);
      procedure SetModified(const Value: Boolean);
  
  
    public
      property Id : Integer read GetId;
      property Name : string read GetName;
      property FirstName : string read FFirstName write SetFirstName;
      property LastName : string read FLastName write SetLastName;
      property Gender : TGender read FGender write SetGender;
      property Modified : Boolean read FModified write SetModified;
      [JSONMarshalled(False)]
      property Picture : TPicture read FPicture write FPicture;
      function Update : Boolean;
      function Delete : Boolean;
  
      constructor Create(AId : Integer; AFirstName, ALastName : string; AGender : TGender); overload;
      destructor destroy; override;
  
      function ToJsonString: string;
      class function FromJsonString(AJSONString: string): TPerson; static;
  
    end;
  
  implementation
  
  { TPerson }
  
  constructor TPerson.Create(AId: Integer; AFirstName, ALastName: string;
    AGender: TGender);
  begin
    inherited Create;
    FPicture := TPicture.Create;
    FId := AId;
    FFirstName := AFirstName;
    FLastName := ALastName;
    FGender := AGender;
  end;
  
  function TPerson.Delete: Boolean;
  begin
    Result := False;
    if (FId &gt; 0) then // if Id below zero we have a problem
    begin
      Result := True;
      FModified := False;
    end;
  end;
  
  destructor TPerson.destroy;
  begin
    FreeAndNil(FPicture);
    inherited;
  end;
  
  function TPerson.GetId: Integer;
  begin
    Result := FId;
  end;
  
  function TPerson.GetName: string;
  begin
    Result := FFirstName + ' ' + FLastName;
  end;
  
  procedure TPerson.SetFirstName(const Value: string);
  begin
    FFirstName := Value;
    FModified := True;
  end;
  
  procedure TPerson.SetGender(const Value: TGender);
  begin
    FGender := Value;
    FModified := True;
  end;
  
  procedure TPerson.SetLastName(const Value: string);
  begin
    FLastName := Value;
    FModified := True;
  end;
  
  procedure TPerson.SetModified(const Value: Boolean);
  begin
    FModified := Value;
  end;
  
  function TPerson.ToJsonString: string;
  var
    JSONMarshal: TJSONMarshal;
  begin
    result := '';
    JSONMarshal := TJSONMarshal.Create(TJSONConverter.Create, True);
    try
      Result := JSONMarshal.Marshal(self).ToString;
    finally
      JSONMarshal.Free;
    end;
  end;
  
  class function TPerson.FromJsonString(AJSONString: string): TPerson;
  var
    JSONUnMarshal: TJSONUnMarshal;
  begin
    JSONUnMarshal := TJSONUnMarshal.Create;
    try
      Result := JSONUnMarshal.Unmarshal(TJSONObject.ParseJSONValue(AJSONString)) as TPerson;
    finally
      JSONUnMarshal.Free;
    end;
  end;
  
  function TPerson.Update: Boolean;
  var
    AStream : TMemoryStream;
  begin
    if (FId &gt; 0) then // if Id below zero we have a problem
    begin
      AStream := TMemoryStream.Create;
      try
        Picture.Graphic.SaveToStream(AStream);
        AStream.Position := 0; // wind back if needed
      finally
        FreeAndNil(AStream);
      end;
    end;
    FModified := False;
  end;
  
  { TPersonsList&lt;T&gt; }
  
  
  end.
  
  
  
  procedure TForm2.Button1Click(Sender: TObject);
  var
    APerson : TPerson;
  begin
  
    APerson := TPerson.Create(1, 'Donald', 'Duck', Male);
    try
  
      Memo1.Lines.Add(APerson.ToJsonString);
  
    finally
      APerson.Free;
    end;
  end;
  </code></pre>