Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

REST request memory leak when no charset is returned in header

Using Delphi 10.2 (Tokyo)

Below is the code for a complete console app that shows an unexpected memory leak (TUTF8Encoding) when one URL is called, and no memory leak when another is called.

Comparing the headers between the two responses:

The one that leaks memory contains

 Content-Type=application/json

The one that does not leak memory contains

 Content-Type=application/json; charset=utf-8

Is this a bug, or should I be doing something to prevent this?

program RESTMemLeakTest;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils, IPPeerClient, REST.Client, REST.Types;

var
  RESTClient1: TRESTClient;
  RESTRequest1: TRESTRequest;
  URL: string;

begin
  ReportMemoryLeaksOnShutdown := True;

  URL := 'https://httpbin.org/post'; // memory leak
  //URL := 'https://jsonplaceholder.typicode.com/posts'; // no memory leak

  RESTClient1 := TRESTClient.Create(URL);
  RESTRequest1 := TRESTRequest.Create(nil);
  try
    try
      RESTRequest1.Client := RESTClient1;
      RESTRequest1.Method := rmPOST;
      RESTRequest1.Execute;
    except
      on E: Exception do
        Writeln(E.ClassName, ': ', E.Message);
    end;
  finally
    RESTRequest1.Free;
    RESTClient1.Free;
  end;
end.

Running the app with the URL that leaks memory returns this:

An unexpected memory leak has occurred. The unexpected small block leaks are:

21 - 28 bytes: TUTF8Encoding x 1

Update: Setting the FallbackCharsetEncoding to an empty string appears to "fix" the memory leak. No known issues (yet) doing this. I'm going to open a bug report with Embarcadero to see what they say. So adding the line below before the request is executed will prevent the unexpected memory leak message.

RESTClient1.FallbackCharsetEncoding := '';

Update 2: Bug report RSP-17695 was submitted on March 30, 2017.

Update 3: August 8, 2017: Bug resolved in version 10.2 Tokyo Release 1

like image 788
Dale M Avatar asked Oct 29 '22 10:10

Dale M


1 Answers

To avoid the memory leak there is a possible workaround for that:

RestClient.FallbackCharsetEncoding := '';

By setting the fallback encoding to empty or 'raw' string the "leaking" branch of the code from the REST library will be not executed and so you will not get the leak of the unreleased instance of TEncoding (which is aquired with GetEncoding()).

But this of course only wokrs if you are OK with using raw encoding fallback.

This works in Berlin Update 2. Probably can work also in later versions before the patch in Tokyo Update 1.

like image 164
Z.B. Avatar answered Nov 15 '22 05:11

Z.B.