Login ProductsSalesSupportDownloadsAbout |
Home » Technical Support » DBISAM Technical Support » Support Forums » DBISAM Client/Server » View Thread |
Messages 1 to 9 of 9 total |
Getting an out of memory error in a stored proc. |
Mon, Nov 13 2006 1:10 PM | Permanent Link |
"Bern Rudisill" | Hello,
I have the following stored proc procedure TMainForm.ServerEngineServerProcedure(Sender: TObject; ServerSession: TDBISAMSession; const ProcedureName: string); var sPathName, sFileName: string; begin if (AnsiCompareText(ProcedureName, 'UploadFile') = 0) then begin with ServerSession do begin sPathName := RemoteParams.ParamByName('PathName').AsString; { get server path } sFileName := RemoteParams.ParamByName('FileName').AsString; { get file name } RemoteParams.ParamByName('ServerFile').SaveToFile(sPathName + sFileName); { save file to server } RemoteParams.Clear; with RemoteParams.CreateParam(ftBoolean, 'Result') do AsBoolean := FileExists(sPathName + sFileName); { set result } end; end else if (AnsiCompareText(ProcedureName, 'DownloadFile') = 0) then begin with ServerSession do begin sPathName := RemoteParams.ParamByName('PathName').AsString; { get server path } sFileName := RemoteParams.ParamByName('FileName').AsString; { get file name } RemoteParams.Clear; RemoteParams.CreateParam(ftBlob, 'File').LoadFromFile(sPathName + sFileName, ftBlob); { Load file to send to client } with RemoteParams.CreateParam(ftBoolean, 'Result') do AsBoolean := FileExists(sPathName + sFileName); { set result } end; end; end; When I call the 'UploadFile' proc it works perfectly, but when I call the 'DownloadFile' proc I keep getting an out of memory error. Any Ideas Here is the code I use to call each procedure from the client function TForm1.UploadFileToServer(sFileName, sFrom, sTo: string): Boolean; begin Memo2.Lines.Insert(0, 'Start Uploading: ' + sFileName); with DBISAMSession1.RemoteParams do begin CreateParam(ftString, 'PathName').AsString := sTo; { set server path } CreateParam(ftString, 'FileName').AsString := sFileName; { set file name } Memo2.Lines.Insert(0, 'Start reading into stream'); CreateParam(ftBlob, 'ServerFile').LoadFromFile(sFrom + sFileName, ftBlob); { load local file } with DBISAMSession1 do begin try Memo2.Lines.Insert(0, 'sending'); CallRemoteProcedure('UploadFile'); { call function } Result := RemoteParams.ParamByName('Result').AsBoolean; { get result of copy } except Result := False; { did not work } end; end; end; Memo2.Lines.Insert(0, 'Done Uploading: ' + sFileName); end; function TForm1.DownLoadFromServer(sFileName, sFrom, sTo: string): Boolean; begin Memo2.Lines.Insert(0, 'Start Downloading: ' + sFileName); with DBISAMSession1.RemoteParams do begin CreateParam(ftString, 'PathName').AsString := sFrom; { set server path } CreateParam(ftString, 'FileName').AsString := sFileName; { set file name } // CreateParam(ftBlob, 'ServerFile').LoadFromFile(sFrom + sFileName, ftBlob); { load local file } with DBISAMSession1 do begin try CallRemoteProcedure('DownloadFile'); { call function } Result := true; except Result := False; { did not work } end; end; end; Memo2.Lines.Insert(0, 'Done Downloading: ' + sFileName); end; Thanks Bern -- |
Mon, Nov 13 2006 4:56 PM | Permanent Link |
Tim Young [Elevate Software] Elevate Software, Inc. timyoung@elevatesoft.com | Bern,
<< When I call the 'UploadFile' proc it works perfectly, but when I call the 'DownloadFile' proc I keep getting an out of memory error. Any Ideas >> How big is the file being transferred ? Your server-side procedure and the calls look fine, so I don't think that there's a coding issue. -- Tim Young Elevate Software www.elevatesoft.com |
Mon, Nov 13 2006 5:25 PM | Permanent Link |
"Bern Rudisill" | Tim Young [Elevate Software] wrote:
> Bern, > > << When I call the 'UploadFile' proc it works perfectly, but when I > call the 'DownloadFile' proc I keep getting an out of memory error. > Any Ideas >> > > How big is the file being transferred ? > > Your server-side procedure and the calls look fine, so I don't think > that there's a coding issue. About 200 megs. I am running the client and server on the same machine for testing. I can transfer the 200 meg file from the client to the server with no errors, but I get the error when trying to send the file from the server to the client. Bern -- |
Tue, Nov 14 2006 9:01 AM | Permanent Link |
Tim Young [Elevate Software] Elevate Software, Inc. timyoung@elevatesoft.com | Bern,
<< About 200 megs. >> That's your problem. Your running out of virtual memory address space. << I am running the client and server on the same machine for testing. I can transfer the 200 meg file from the client to the server with no errors, but I get the error when trying to send the file from the server to the client. >> Are you performing one after the other ? Or separately ? -- Tim Young Elevate Software www.elevatesoft.com |
Tue, Nov 14 2006 9:42 AM | Permanent Link |
"Bern Rudisill" | Tim Young [Elevate Software] wrote:
> Bern, > > << About 200 megs. >> > > That's your problem. Your running out of virtual memory address > space. > > << I am running the client and server on the same machine for > testing. I can transfer the 200 meg file from the client to the > server with no errors, but I get the error when trying to send the > file from the server to the client. >> > > Are you performing one after the other ? Or separately ? Is there a way to increase the virtual memory address? I don't understand why the Server would act any different then the Client. Here is my code that calls the stored procs. In Client: procedure TForm1.Button6Click(Sender: TObject); var i: Integer; sFrom: string; sTo: string; begin txtStart.text := 'Start: ' + timetostr(now); DBISAMSession1.RemoteHost := txtRemoteHost.text; DBISAMSession1.RemoteAddress := txtRemoteAddress.Text; sFrom := 'C:\Documents and Settings\bernr\Desktop\Test\data\'; sTo := 'D:\Projects\ExitCare6\ExitCare 6.4\Release\test\'; for i := 0 to Memo1.lines.Count - 1 do begin DownLoadFromServer(memo1.lines.Strings[i] + '.blb', sFrom, sTo); DownLoadFromServer(memo1.lines.Strings[i] + '.idx', sFrom, sTo); DownLoadFromServer(memo1.lines.Strings[i] + '.dat', sFrom, sTo); end; txtEnd.text := 'Done: ' + timetostr(now); showmessage('Done'); end; function TForm1.DownLoadFromServer(sFileName, sFrom, sTo: string): Boolean; begin Memo2.Lines.Insert(0, 'Start Downloading: ' + sFileName); with DBISAMSession1.RemoteParams do begin CreateParam(ftString, 'PathName').AsString := sFrom; { set server path } CreateParam(ftString, 'FileName').AsString := sFileName; { set file name } with DBISAMSession1 do begin try CallRemoteProcedure('DownloadFile'); { call function } if RemoteParams.ParamByName('Result').AsBoolean = true then RemoteParams.ParamByName('File').SaveToFile(sTo + sFileName); { save file } // showmessage(booltostr(RemoteParams.ParamByName('Result').AsBoolean, true)); RemoteParams.Clear; Result := true; except Result := False; { did not work } end; end; end; Memo2.Lines.Insert(0, 'Done Downloading: ' + sFileName); end; Stored Proc in Server: if (AnsiCompareText(ProcedureName, 'DownloadFile') = 0) then begin with ServerSession do begin sPathName := RemoteParams.ParamByName('PathName').AsString; { get server path } sFileName := RemoteParams.ParamByName('FileName').AsString; { get file name } RemoteParams.Clear; if FileExists(sPathName + sFileName) then begin { If the file exists, use the TDBISAMParam LoadFromFile method to load the file data into the parameter } RemoteParams.CreateParam(ftblob, 'File').LoadFromFile(sPathName + sFileName, ftBlob); end else { If the file doesn't exist, just create a NULL parameter with the correct result name } RemoteParams.CreateParam(ftblob,'File'); RemoteParams.CreateParam(ftBoolean, 'Result').AsBoolean:= FileExists(sPathName + sFileName); { set result } end; end Is there a better way to copy tables from the server to the local machine? I thought about embedding an FTP server in the DBISAM server to copy the files, but would rather do this as a last resort. Bern -- |
Wed, Nov 15 2006 3:56 PM | Permanent Link |
"Bern Rudisill" | Bern Rudisill wrote:
> Tim Young [Elevate Software] wrote: > > > Bern, > > > > << About 200 megs. >> > > > > That's your problem. Your running out of virtual memory address > > space. > > > > << I am running the client and server on the same machine for > > testing. I can transfer the 200 meg file from the client to the > > server with no errors, but I get the error when trying to send the > > file from the server to the client. >> > > > > Are you performing one after the other ? Or separately ? > > > Is there a way to increase the virtual memory address? I don't > understand why the Server would act any different then the Client. > > Here is my code that calls the stored procs. > > In Client: > > procedure TForm1.Button6Click(Sender: TObject); > var > i: Integer; > sFrom: string; > sTo: string; > begin > txtStart.text := 'Start: ' + timetostr(now); > DBISAMSession1.RemoteHost := txtRemoteHost.text; > DBISAMSession1.RemoteAddress := txtRemoteAddress.Text; > > sFrom := 'C:\Documents and Settings\bernr\Desktop\Test\data\'; > sTo := 'D:\Projects\ExitCare6\ExitCare 6.4\Release\test\'; > > for i := 0 to Memo1.lines.Count - 1 do > begin > DownLoadFromServer(memo1.lines.Strings[i] + '.blb', sFrom, sTo); > DownLoadFromServer(memo1.lines.Strings[i] + '.idx', sFrom, sTo); > DownLoadFromServer(memo1.lines.Strings[i] + '.dat', sFrom, sTo); > end; > txtEnd.text := 'Done: ' + timetostr(now); > showmessage('Done'); > end; > > function TForm1.DownLoadFromServer(sFileName, sFrom, sTo: string): > Boolean; > begin > Memo2.Lines.Insert(0, 'Start Downloading: ' + sFileName); > with DBISAMSession1.RemoteParams do > begin > CreateParam(ftString, 'PathName').AsString := sFrom; { set > server path } > CreateParam(ftString, 'FileName').AsString := sFileName; { set > file name } > with DBISAMSession1 do > begin > try > CallRemoteProcedure('DownloadFile'); { call function } > if RemoteParams.ParamByName('Result').AsBoolean = true > then RemoteParams.ParamByName('File').SaveToFile(sTo + > sFileName); { save file } > // > showmessage(booltostr(RemoteParams.ParamByName('Result').AsBoolean, > true)); > RemoteParams.Clear; > Result := true; > except > Result := False; { did not work } > end; > end; > end; > Memo2.Lines.Insert(0, 'Done Downloading: ' + sFileName); > end; > > Stored Proc in Server: > > if (AnsiCompareText(ProcedureName, 'DownloadFile') = 0) then > begin > with ServerSession do > begin > sPathName := > RemoteParams.ParamByName('PathName').AsString; { get server path } > sFileName := > RemoteParams.ParamByName('FileName').AsString; { get file name } > RemoteParams.Clear; > if FileExists(sPathName + sFileName) then > begin > { If the file exists, use the TDBISAMParam > LoadFromFile method to load the file > data into the parameter } > RemoteParams.CreateParam(ftblob, > 'File').LoadFromFile(sPathName + sFileName, ftBlob); > end > else > { If the file doesn't exist, just create a NULL > parameter with the correct result name } > RemoteParams.CreateParam(ftblob,'File'); > RemoteParams.CreateParam(ftBoolean, 'Result').AsBoolean:= > FileExists(sPathName + sFileName); { set result } > end; > end > > Is there a better way to copy tables from the server to the local > machine? I thought about embedding an FTP server in the DBISAM server > to copy the files, but would rather do this as a last resort. > > Bern -- A Little more Info, I went stepping trough the dbisamsv code and found the error is happening on line # 5890 Pack((RecordBuffer+Offset)^,(FLDCHG_DATA+DataSize)), which is weird because it seems to of had no error when it called the pack procedure on the actual blob. once it gets into the pack procedure the actual like that is erroring out is line # 1287 ResizeSendBuffer(FPackPos+SizeOf(Integer)+BufferSize); FPack = 193096762 Sizeof(Integer)=4 BufferSize=3 Total=193096769 I stopped tracing it there. |
Wed, Nov 15 2006 4:18 PM | Permanent Link |
Tim Young [Elevate Software] Elevate Software, Inc. timyoung@elevatesoft.com | Bern,
<< A Little more Info, I went stepping trough the dbisamsv code and found the error is happening on line # 5890 Pack((RecordBuffer+Offset)^,(FLDCHG_DATA+DataSize)), which is weird because it seems to of had no error when it called the pack procedure on the actual blob. once it gets into the pack procedure the actual like that is erroring out is line # 1287 ResizeSendBuffer(FPackPos+SizeOf(Integer)+BufferSize); FPack = 193096762 Sizeof(Integer)=4 BufferSize=3 Total=193096769 I stopped tracing it there. >> It is trying to resize the comms buffer that is already 193 megs or so, which means that close to 400 megs of contiguous address space will be required out of the 2 Gigs of virtual address space. There's a good chance that there will never be that much contiguous address space available, hence the out of memory error. You probably need to start looking at an option that doesn't involve buffering the entire 200 meg file during transmission. The parameter streaming in DBISAM is only intended to be used with small files (0-10 megs). -- Tim Young Elevate Software www.elevatesoft.com |
Wed, Nov 15 2006 6:20 PM | Permanent Link |
"Bern Rudisill" | Tim Young [Elevate Software] wrote:
> Bern, > > << A Little more Info, I went stepping trough the dbisamsv code and > found the error is happening on line # 5890 > Pack((RecordBuffer+Offset)^,(FLDCHG_DATA+DataSize)), which is weird > because it seems to of had no error when it called the pack procedure > on the actual blob. once it gets into the pack procedure the actual > like that is erroring out is line # 1287 > ResizeSendBuffer(FPackPos+SizeOf(Integer)+BufferSize); FPack = > 193096762 Sizeof(Integer)=4 BufferSize=3 > > Total=193096769 > > I stopped tracing it there. >> > > It is trying to resize the comms buffer that is already 193 megs or > so, which means that close to 400 megs of contiguous address space > will be required out of the 2 Gigs of virtual address space. There's > a good chance that there will never be that much contiguous address > space available, hence the out of memory error. You probably need > to start looking at an option that doesn't involve buffering the > entire 200 meg file during transmission. The parameter streaming in > DBISAM is only intended to be used with small files (0-10 megs). I can understand that, but what I don't understand is why it works sending a 200m filed to the server but not from the server. Remember both the client and server are running on the same system. Do you happen to have any suggestions on how to copy tables from the server to the local system? We do this so that they always read from the local system to limit network bandwith and for speed. I am thinking about embedding an FTP or HTTP server with the DBISAM server for file transfers. Would ElevateDB handle this better? -- |
Thu, Nov 16 2006 3:45 PM | Permanent Link |
Tim Young [Elevate Software] Elevate Software, Inc. timyoung@elevatesoft.com | Bern,
<< I can understand that, but what I don't understand is why it works sending a 200m filed to the server but not from the server. Remember both the client and server are running on the same system. >> It doesn't matter - they're two different processes, hence they will have two completely-separate virtual address spaces. << I am thinking about embedding an FTP or HTTP server with the DBISAM server for file transfers. >> That might be the best option for now. Either that, or stream chunks of the records from one table to the other instead of trying to transfer the whole table like a file. However, that will most likely take a bit longer. << Would ElevateDB handle this better? >> Not at the moment, no. However, we do have plans to add file-transfer capabilities at some point. -- Tim Young Elevate Software www.elevatesoft.com |
This web page was last updated on Friday, September 20, 2024 at 05:39 PM | Privacy PolicySite Map © 2024 Elevate Software, Inc. All Rights Reserved Questions or comments ? E-mail us at info@elevatesoft.com |