Re: FCGI/perl memory leakage

Stanley Gambarin (
Fri, 04 Apr 1997 15:05:01 -0500

Message-Id: <>
To: (Sven Verdoolaege)
Subject: Re: FCGI/perl memory leakage 
In-Reply-To: Your message of "Wed, 02 Apr 1997 15:03:53 +0200."
Date: Fri, 04 Apr 1997 15:05:01 -0500
From: Stanley Gambarin <>

> On Apr 1, (Sven Verdoolaege) wrote:
> ...
> I think I've located the problem.
> perl is trying to be smart and postpones the desruction of hash elements
> till ... never in this case.
> Quick solution is to uncomment the hv_delete in line 172 of FCGI.xs .
> This may have unwanted side effects.
> Complete solution will take some more time and someone (Stanley ?)
> to explain to me what all this environment stuff is supposed to do.
	Ok, I have looked at the code and i think i have an idea
of what is happening, so I will try to explain:
	- once the request is recieved, we call accept() function
in FCGI.xs.  Each request has an environment stuff that is associated 
with it, which is passed via -initial-env in AppClass for Apache. 
The per request environment is stored in the requestEnvrion, so 
the following code is inside the accept():

	savedEnviron = environ;
        acceptStatus = FCGI_Accept();
        requestEnviron = environ;
        environ = savedEnviron;
	These manipulations are done since FCGI_Accept() modifies the 
global environ, but we need to save it for later uses.  So, after we 
got our new environment, we have to set it up by calling
DoPerlEnv(requestEnviron, TRUE);  Finally, at the top, we call the 
DoPerlEnv(requestEnviron, FALSE) to disable the request environment from
the previous request.  If you follow the above suggestion and remove call
to hv_delete() in DoPerlEnv, then if you have 2 requests for the same 
fastcgi app with different environments, then the second request will also
get the environment of the first request, which is a no-no :0.

	The problem with hv_delete() as was correctly stated is that 
the elements are marked for deletion, but the memory is never actually 
freed up.  (in hv.c:hv_delete() you can see the element gets marked
for lazy deletion, but not hv_free()d).  I guess the proper way to 
handle it is to invoke immediate purge of the array, however, I am
not very familiar with Perl API, so I am at loss on how to do it.
Another alternative, which I think would be easier to implement is as 
follows, in DoPerlEnv:
	hv = perl_get_hv("ENV", TRUE);
	backup = HV_copy?(hv);    /* save existing Perl environment */
	if (set==TRUE) then proceed as before.
	if (set==FALSE) /* need to remove the elements */
	delete_hv(hv);  /* remove it completely.. should free memory */
	hv = HV_copy?(backup);    /* copy back the initial values */

	Like I said before, I am not very familiar with the Perl's insides,
so if you (Sven) can find the solution to the above and then email it to me.

						Hope that was of some help.