Memory is not freed after response in FPweb embedded server lazarus / 38-Networking and Web Programming ---------------------------------------------------------------------- alantelles · 2020-07-12 20:29 Good afternoon (or any time it is). I'm developing an application that makes use of FPweb embedded server. So I decided to look at the system manager to monitoring memory usage while using the application. And I realized that after the response the memory usage didn't fall back to the level it was before request. And the memory usage increase after every request. Is this the default behavior? Is there a way to cleanup memory after response? ---------------------------------------------------------------------- egsuh · 2020-07-13 05:05 Well, if you are using CGI module, then check the Kind property of TFPWebModule. If it is wkPooled, change it to wkOneShot and monitor again. I'm concerned with this issue quite much.  Hope to know your result. ---------------------------------------------------------------------- alantelles · 2020-07-13 14:07 I,m using FPWeb embedded server only without graphical component. Here's a sample For configuring server Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i constructor TUltraGenServer.Create(APort: word; AnApp: string; Mode:string);{... lots of code ...}  HTTPRouter.RegisterRoute('/favicon.ico', @LoadFavIcon);  HTTPRouter.RegisterRoute('*', @ExecuteAction);  This route is registered to '*' because a script will actually control the routing. For start the server Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i function TUltraGenServer.RunServer:boolean;begin  if not FDontServe then  begin    WriteLn('Running server at port: ', FPort);    Application.Title := 'UltraGen server 1.0';    Application.Port := FPort;    Application.Threaded := True;    Application.Initialize;    Application.Run;    Result := True;  end  else    Result := False;end; Don't know if I can do the test with FCGI module due to the behaviour of FCGI apps. ---------------------------------------------------------------------- Leledumbo · 2020-07-16 10:00 Since you're writing your own server app using the embedded server, we cannot see how you manage whatever comes in and out of the embedded server. One thing I can assure you, this program: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i {$mode objfpc}{$H+} uses  classes, sysutils, webutil, fphttpapp, httproute, httpdefs; procedure handle(req: TRequest; resp: TResponse);var  s: tstrings;begin  s := TStringList.Create;  with s do    try      DumpRequest(req,s,true);      resp.Content := s.Text;    finally      s.Free;    end;end; begin  Application.Port := 9090;  HTTPRouter.RegisterRoute('*',@handle);  Application.Run;end. leaks no memory, called 10000 times the RAM usage stays at 4MB. ---------------------------------------------------------------------- alantelles · 2020-07-19 14:20 At first: honoured for being replied by you. About the question: that's the reply I waited for being in peace about this. I'll review my application to see the points where I'm not freeing memory. In fact, my app uses a lot of dinamically create objects and it's getting hard to track them to free memory in a secure way without cause an access Violation. Since it doesn't do heavy things it's not a problem now but in many requests, it is. ---------------------------------------------------------------------- alantelles · 2020-07-19 14:27 Quote from: Leledumbo on July 16, 2020, 12:00:37 pmSince you're writing your own server app using the embedded server, we cannot see how you manage whatever comes in and out of the embedded server. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i  AInter := TInterpreter.Create(ATree);      AInter.Interpret;    Output := AInter.PLive;    //AInter.FreeInstances;    AInter.Free;    AParser.Free;    ALexer.Free;    AResponse.Content := Output;    WriteLn(#13+'['+FormatDateTime('yyyy-mm-dd hh:nn:ss.zzz', Now)+'] ' +      ARequest.Method + ': '+      ARequest.URI+' -- '+ IntToStr(AResponse.Code)+      ' ' + AResponse.CodeText +      ', ' + IntToStr(AResponse.ContentLength) + ' B', #13);   The main section, who creates and free the elements of response is this. I thought that after the response it would clear itself. By the way, I really got to review my interpreter code. ---------------------------------------------------------------------- alantelles · 2020-07-19 21:00 In time: @leledumbo, I visited your GitHub and saw the template engineering and parsers seem to be a subject of your interest. Would you like to contribute at UltraGen project? I'm developing a brand new programming language specifically designed to create web pages. It can use plain and script text mixed like PHP but with modern approaches and strongly typed. Maybe you can find it interesting. Here is the link https://github.com/alantelles/ultragen/tree/refactor Greetings ---------------------------------------------------------------------- Leledumbo · 2020-07-20 06:49 Quote from: alantelles on July 19, 2020, 04:27:27 pmCode: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i  AInter := TInterpreter.Create(ATree);      AInter.Interpret;    Output := AInter.PLive;    //AInter.FreeInstances;    AInter.Free;    AParser.Free;    ALexer.Free;    AResponse.Content := Output;    WriteLn(#13+'['+FormatDateTime('yyyy-mm-dd hh:nn:ss.zzz', Now)+'] ' +      ARequest.Method + ': '+      ARequest.URI+' -- '+ IntToStr(AResponse.Code)+      ' ' + AResponse.CodeText +      ', ' + IntToStr(AResponse.ContentLength) + ' B', #13);  The main section, who creates and free the elements of response is this. I thought that after the response it would clear itself. By the way, I really got to review my interpreter code. I don't see ATree being Free-d, and if it eventually is, no guarantee it will free its children recursively as well. I'd say compile with -glh and you will get a proper stacktrace. AResponse, if it comes as HTTPRouter route's parameter, will be handled outside your registered handler, so no need to free it manually (in fact, don't). Quote from: alantelles on July 19, 2020, 11:00:06 pmIn time: @leledumbo, I visited your GitHub and saw the template engineering and parsers seem to be a subject of your interest. Would you like to contribute at UltraGen project? I'm developing a brand new programming language specifically designed to create web pages. It can use plain and script text mixed like PHP but with modern approaches and strongly typed. Maybe you can find it interesting. Here is the link https://github.com/alantelles/ultragen/tree/refactor Greetings I consider that one kind of shitty, as it was made with classic single person programming in mind. Nowadays we made frontend totally separate from backend, which is glued by HTTP contract. I'm sorry I don't have time for such a project. Outside my main job, I only make things that I consider useful for me and only then I share it with the world. ---------------------------------------------------------------------- alantelles · 2020-07-20 12:22 Thanks for reply. It's a pity I can't have you at the project but your answers contributed to me somehow. I'll review the destructors to clean all objects. About the project, anytime you change your mind a bit feel invited.