I get error “Out of memory” when I try to send large binary data by RemObjects


(Taras Karpuk) #1


I get error “Out of memory” when I try to send binary data by RemObjects.

My system’s parameters:

Windows 7 64bit
RAM 3 Gb
Delphi XE5
Rem Objects SDK

My application is run as NT service (by Administrator). I try to send binary data by SOAP on the method:

function TSession.GetItemDataByDoc(const DocNo: Integer; out ItemInfo: TStructItemInfo): Integer;
ItemInfo := TStructItemInfo.Create;
ItemInfo.ItemData := Binary.Create;
ItemInfo.ItemData.Position := 0;
ItemInfo.ItemData.LoadFromFile(Format(‘C:\tmp%d.rar’, [DocNo]));

TStructItemInfo = class(TROComplexType)

fItemTitle: UnicodeString;
fItemType: UnicodeString;
fItemData: Binary;
fSystemName: UnicodeString;

code of DFM:

object ROServer: TROIndyHTTPServer
Dispatchers = <
Name = 'ROMessage’
Message = ROMessage
Enabled = True
PathInfo = 'SOAP’
OnReadFromStream = ROServerReadFromStream
SendClientAccessPolicyXml = captAllowAll
IndyServer.Bindings = <>
IndyServer.DefaultPort = 8095
Port = 8095
object ROMessage: TROSOAPMessage
Envelopes = <>
SerializationOptions = [xsoWriteMultiRefArray, xsoWriteMultiRefObject]
object SessionManager: TROInMemorySessionManager
MaxSessions = 500
OnBeforeDeleteSession = SessionManagerBeforeDeleteSession

And I try to get this data on client side (ASP classic, VB script).

If I try to send file more than 100-150 Mb – My application use very large size of memory. For example:
File size – 190 Mb → used memory 1120 Mb, File size – 280 Mb → used memory 2200 Mb.
And if I try to send file more - I get the error “Out of memory”. This exception occurs in the RO internal method:

procedure TSession_Invoker.Invoke_GetItemDataByDoc(const __Instance:IInterface; const __Message:IROMessage; const __Transport:IROTransport; out __oResponseOptions:TROResponseOptions);
{ function GetItemDataByDoc(const DocNo: Integer; out ItemInfo: TStructItemInfo): Integer; }
DocNo: Integer;
ItemInfo: VEntWebLib_Intf.TStructItemInfo;
lResult: Integer;
__lObjectDisposer: TROObjectDisposer;
CheckRoles(__Instance, GetDefaultServiceRoles);
ItemInfo := nil;
__Message.Read(‘DocNo’, TypeInfo(Integer), DocNo, []);

lResult := (__Instance as ISession).GetItemDataByDoc(DocNo, ItemInfo);
__Message.InitializeResponseMessage(__Transport, 'VEntWebLib', 'Session', 'GetItemDataByDocResponse');
__Message.Write('Result', TypeInfo(Integer), lResult, []);

// Exception this! ----------------------
__Message.Write(‘ItemInfo’, TypeInfo(VEntWebLib_Intf.TStructItemInfo), ItemInfo, []);
// -------------------------------------------

__lObjectDisposer := TROObjectDisposer.Create(__Instance);

I use FastMM4 {$SetPEFlags $20} in my project but it don’t help.
I tried to use last version of RemObjects SDK (v. 9 - trial), but I still got the error.

  1. Can you help me to fix this error?
  2. What the maximal size for sending binary data in RemObjects?
  3. How do the size depends on the system parameters (32 or 64, RAM, ext.)?

(EvgenyK) #2

I think, reason for such error can be: your original big binary data is transformed into XML. later this XML is written into internal buffer of Indy ( or Synapse).
while Indy are sending their stream to client, all objects (original data, xml, internal buffer of Indy) are stored in memory.
In worse case, “Out of memory” can be fired.

I can recommend to send such big data in small chunks. see Extended File Transfer and File Broadcast samples

(Taras Karpuk) #3

Thanks for your reply.
I thought to use a portion of the file to send, but in my client - classic ASP and I have not really presented as it implement the code for the client Delphi.
I think - I can write DLL (by Delphi), but it needs for only 1 case.