Recent

Author Topic: [SOLVED] FastCGI - releasing memory  (Read 457 times)

egsuh

  • Hero Member
  • *****
  • Posts: 563
[SOLVED] FastCGI - releasing memory
« on: November 01, 2020, 09:05:38 am »
I'm keeping writing on this subject, hoping that somebody find a solution.

Based on several experiments, I came to think that problems with FastCGI & wkPooled (value for property Kind of TFPWebModule) are related with memories allocated are not released.

IIS of Windows (in my case) creates new instance of web app, if there are new requests while previous instance is still running processing previous request. After predefined idle time (default is 5 minutes in case of IIS), the instance is released.

Problem is this does not seem to release allocated within the application.  That is, destructor Destroy is not called. For example, I tried followings.

Code: Pascal  [Select][+][-]
  1. unit web1;
  2. interface
  3. ...
  4. implementation
  5. ...
  6. initialization
  7.     Log('initialization called');  // procedure Log just write the text string to a file.  
  8. finalization
  9.     Log('finalization called');
  10. end.
  11.  


Here, initialization is called several times --- at first access, there is a log.
After 10 minutes of no access, I access to the web server again, and there is another log, but only initialization. So the application must have been dumped and re-created. But 'finalization' is never logged.

I think the same happens at the web module level --- when it is set as wkPooled. I can see logs of  DataModuleCreate, but not of DataModuleDestroy.

These are just guesses anyway. But if there are some methods to solve these problems, please let me know so that I can test it.   
« Last Edit: November 02, 2020, 09:31:08 am by egsuh »

PascalDragon

  • Hero Member
  • *****
  • Posts: 2583
  • Compiler Developer
Re: FastCGI - releasing memory
« Reply #1 on: November 01, 2020, 05:00:51 pm »
Here, initialization is called several times --- at first access, there is a log.
After 10 minutes of no access, I access to the web server again, and there is another log, but only initialization. So the application must have been dumped and re-created. But 'finalization' is never logged.

Per process an initialization section will only be called once. And finalization will not be called should the server decide to simply terminate the created process.

egsuh

  • Hero Member
  • *****
  • Posts: 563
Re: FastCGI - releasing memory
« Reply #2 on: November 02, 2020, 08:15:05 am »
Quote
Per process an initialization section will only be called once. And finalization will not be called should the server decide to simply terminate the created process.

Then are the memories allocated within the application freed? I guess so, but cannot quite sure.
For example,

Code: Pascal  [Select][+][-]
  1. unit web1;
  2. interface
  3. ...
  4. implementation
  5. ...
  6. initialization
  7.      AStringList := TStringList.Create;
  8. finalization
  9.     AStringList.Free;
  10. end.

In this case, is AStringList freed?  Not sure whether this is necessary or I may be thinking quite absurd thing. But there are reports on memory leakage in the fcgi module. So I'm checking every possibility.

PascalDragon

  • Hero Member
  • *****
  • Posts: 2583
  • Compiler Developer
Re: FastCGI - releasing memory
« Reply #3 on: November 02, 2020, 09:20:56 am »
Quote
Per process an initialization section will only be called once. And finalization will not be called should the server decide to simply terminate the created process.

Then are the memories allocated within the application freed? I guess so, but cannot quite sure.

If you free something in the finalization section then it will be executed upon cooperative termination of the process. If the process is however terminated from outside, then they won't be executed.

Please be aware however that in both cases all resources allocated by the process will return to the operating system anyway. So finding memory leaks upon the termination of a process should mainly ensure that a long running process doesn't leak unnecessary or that destructors that might clean up things (e.g. removing some temporary files) are called correctly.

egsuh

  • Hero Member
  • *****
  • Posts: 563
Re: FastCGI - releasing memory
« Reply #4 on: November 02, 2020, 09:30:48 am »
Quote
in both cases all resources allocated by the process will return to the operating system anyway.

Okay, thank you. So I thought my idea may be absurd. No one will build such a careless OS.

But sometimes I had problem with my program, just because I did not initialized a variable, for example, a string type variable. I expected it to be null string (''), but it had string value of previous run. The process should have exited, but did not.

PascalDragon

  • Hero Member
  • *****
  • Posts: 2583
  • Compiler Developer
Re: FastCGI - releasing memory
« Reply #5 on: November 02, 2020, 09:43:13 am »
Okay, thank you. So I thought my idea may be absurd. No one will build such a careless OS.

Though that shouldn't stop you from making sure that your program has as few leaks as possible as more often than not they aren't from things that are allocated in the beginning and (supposed to be) freed at the end, but things that are allocated in between and forgotten. In case of e.g. FastGCI processes or other long running processes that would result in unnecessary resource usage.

But sometimes I had problem with my program, just because I did not initialized a variable, for example, a string type variable. I expected it to be null string (''), but it had string value of previous run. The process should have exited, but did not.

If you have code like the following then this is indeed a possibility:

Code: Pascal  [Select][+][-]
  1. function Test: String;
  2. begin
  3.   SetLength(Result, 5);
  4.   // ...
  5. end;

Depending on when and how it's called it might indeed be the case that Result calls valid data from a function call before that which returned a String as well. Thus you should always do this:

Code: Pascal  [Select][+][-]
  1. function Test: String;
  2. begin
  3.   Result := '';
  4.   SetLength(Result, 5);
  5.   // ...
  6. end;

The same also applies to functions returning dynamic arrays.

 

TinyPortal © 2005-2018