Message-Id: <199704042005.PAA03861@u4-138.openmarket.com> To: email@example.com (Sven Verdoolaege) Subject: Re: FCGI/perl memory leakage In-Reply-To: Your message of "Wed, 02 Apr 1997 15:03:53 +0200." <19970402150353.DV39224@breughel.ufsia.ac.be> Date: Fri, 04 Apr 1997 15:05:01 -0500 From: Stanley Gambarin <gambarin@OpenMarket.com> > On Apr 1, firstname.lastname@example.org (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. Stanley.