Monday 30 April 2018

Potential fix to Delphi XE5 Datasnap memory leak issue

As we all know for a long time, Datasnap causes a lot of memory leak even for the simple App Server method call. I can reproduce the issue with Delphi XE5 by running simple test application multiple times. The test application only opens the connection, calls an App Server method (does nothing) and then close the connection and also close the application if succeed (otherwise system will hang due to lack of resources). With any Datasnap test application, to reproduce the issue you only need to execute 500 instances of test client as a batch; once repeat the batch 7 times, the App Server memory usage reaches around 4G (with the help of adding {$SetPEFlags IMAGE_FILE_LARGE_ADDRESS_AWARE} in the App Server project file).

After digging into the source codes of Datasnap for some time, I think I might have found the problem. In the procedure of TDSTCPServerTransport.DoOnDisconnect, some handlers and the associated DBX objects are not freed. You can find them in the function of TDSJSONProtocolHandlerFactory.CreateProtocolHandler.

I believe that the new lines between "//fix" in the following procedure fix the major memory leak. Another change is to add the following line to the App Server method as pointed out by a lot of people.

GetInvocationMetadata.CloseSession := True;

I've retested the same secnario as above, the App Server memory usage only reaches 41M.

procedure TDSTCPServerTransport.DoOnDisconnect(AContext: IIPContext);
var
  TempData: TObject;
  Event: TDSTCPDisconnectEventObject;
begin
  if Assigned(FTDSTCPDisconnectEvent) and (AContext <> nil) and (AContext.Connection <> nil) and
    (FTcpServer <> nil) and FTcpServer.Active then
  begin
    Event := TDSTCPDisconnectEventObject.Create(AContext.Connection.GetObject);
    try
      OnDisconnect(Event);
    except
    end;
  end;
  TempData := AContext.Data;
  //fix - start
  if TempData is TDBXJSonServerProtocolHandler then
  begin
    AContext.Data := nil;
    (TempData as TDBXJSonServerProtocolHandler).Free;
  end
  else
  //fix - end
  begin
    AContext.Data := nil;
    TempData.Free;
  end;
{$IFNDEF POSIX}
  CoUninitialize;
{$ENDIF}
end;

BTW, I've downloaded Delphi 10.2.3 trial and rebuilt the App Server, however it still has the memory leak issue.

Saturday 2 March 2013

How to connect Sony Xperia S Tablet with adb protocol through USB?

There is a FAQ on Sony's website. Please see the link as below.

http://www.sony.com.au/support/faq/474653/product/sgpt122au

Unfortunately, it didn't resolve the issue. I followed the steps in FAQ many times, while system (Windows 7) still couldn't find the driver.

When checked the device properties, I found the following page which showing the Hardware Ids.

Then I did the search with those Ids, found the descriptions as below. And append those descriptions into android_winusb.inf file, then tried to update the driver again. It worked!

;SONY Sony Tablet P
%SingleAdbInterface% = USB_Install, USB\VID_054C&PID_04D2
%CompositeAdbInterface% = USB_Install, USB\VID_054C&PID_04D2&MI_01
;SONY Sony Tablet S
%SingleAdbInterface% = USB_Install, USB\VID_054C&PID_05B4
%CompositeAdbInterface% = USB_Install, USB\VID_054C&PID_05B4&MI_01
;SONY Xperia Tablet S
%SingleAdbInterface% = USB_Install, USB\VID_054C&PID_06AD
%CompositeAdbInterface% = USB_Install, USB\VID_054C&PID_06AD&MI_01
;SONY Walkman Z
%SingleAdbInterface% = USB_Install, USB\VID_054C&PID_0691
%CompositeAdbInterface% = USB_Install, USB\VID_054C&PID_0691&MI_01

Hope this can help people save some time.