Discussion:
Memory management when using embeded Perl interpreter
(too old to reply)
Eduardo M KALINOWSKI
2005-09-29 19:37:20 UTC
Permalink
Hi,

I have a problem with memory management when using a Perl
interpreter embeded in my application as described in perlembed. I'm not
sure if this is the right mailing list for this kind of question, but I
could not find a better one.

Anyway, my problem lies in the function perl_match that I give
below. If this function is called many times, the memory comsumption of
my program gets very high, so there must be a leak somewhere. However,
the only thing that I'm sure gets created there (the command SV) has its
reference count decreased. So, is there anything else that must be
free()'d, that must have its reference count decreased, etc?

I'm attaching a simple program that calls that function many times
for test purposes. A couple of notes: the function has some extra
features (such as requesting a PerlInterpreter to be passed, setting
$string to be UTF-8, etc) because I've taken the function directly from
my program, which can have several perl interpreters at the same time
among other things. Also, it probably is not the best to create the
command SV each run, since the contents do not change between runs.
However, I've already tried making command a static variable created
only once, and this did not solve the problem. So I guess I'm doing
something wrong somewhere else.

Here's the function, along with support functions to see the problem:
#include <stdlib.h>
#include <stdio.h>
#include <EXTERN.h>
#include <perl.h>
#include <XSUB.h>

int
perl_match(PerlInterpreter *interpreter,
const char *line,
SV *pattern_re)
{
SV *string;
SV *re;
SV *command = NULL;
SV *retval;
dSP;

PERL_SET_CONTEXT(interpreter);

/* Set the string in a variable */
string = get_sv("triggerline", TRUE);
sv_setpv(string, (char *) line);
SvUTF8_on(string);
/* Set the regexp in a variable */
re = get_sv("_re", TRUE);
sv_setsv(re, pattern_re);
/* Create the command to run */
command = newSVpvf("$triggerline =~ tr/\\n\\r//d;"
"my @__M = ($triggerline =~ m<$_re>);"
"my $match = scalar @__M;"
"if ($match) {"
" @_ = @__M;"
" unshift(@_, $triggerline);"
"}"
"$match;");

/* Run the command */
PUSHMARK(SP);
eval_sv(command, G_SCALAR);
SPAGAIN;
retval = POPs;
PUTBACK;

SvREFCNT_dec(command);

return SvIV(retval);
}


SV *
precompute_re(PerlInterpreter *interpreter,
const char *re_string)
{
SV *re_int;
SV *re_new;
SV *command;
dSP;

PERL_SET_CONTEXT(interpreter);

command = newSVpvf("$_re = qr<%s>;", re_string);
PUSHMARK(SP);
eval_sv(command, G_SCALAR);
SPAGAIN;
re_int = POPs;
PUTBACK;

SvREFCNT_dec(command);

re_new = newSVsv(re_int);
return re_new;
}


int
main(int argc, char *argv[])
{
char *line = "Just some line to match.";
PerlInterpreter *perl_interpreter;
SV *re;
char *my_argv[] = { "test", "-e", "0" };
int i;

PERL_SYS_INIT3(&argc, &argv, NULL);
perl_interpreter = perl_alloc();
perl_construct(perl_interpreter);
PERL_SET_CONTEXT(perl_interpreter);
perl_parse(perl_interpreter, NULL, 3, my_argv, (char **)NULL);

re = precompute_re(perl_interpreter, "regexp");

printf("Starting...\n");
for (i = 0; i < 100000; ++i) {
perl_match(perl_interpreter, line, re);
if ((i % 10000) == 0) {
printf("%d\n", i);
}
}
printf("Done, destructing...\n");

perl_destruct(perl_interpreter);
perl_free(perl_interpreter);
PERL_SYS_TERM();

printf("Exiting.\n");
return 0;
}
--
The advertisement is the most truthful part of a newspaper.
-- Thomas Jefferson

Eduardo M KALINOWSKI
***@bol.com.br
http://move.to/hpkb
Jeremy White
2005-09-30 08:49:07 UTC
Permalink
Post by Eduardo M KALINOWSKI
I have a problem with memory management when using a Perl
interpreter embeded in my application as described in perlembed. I'm not
sure if this is the right mailing list for this kind of question, but I
could not find a better one.
As a guess it's because the variables used within the eval aren't being
freed. Try something like:

dSP;
ENTER ;
SAVETMPS ;
PUSHMARK(SP);
//do you eval here
FREETMPS ;
LEAVE ;

and see if that makes a difference.

Cheers,

jez.
Eduardo M KALINOWSKI
2005-09-30 13:49:51 UTC
Permalink
Post by Jeremy White
Post by Eduardo M KALINOWSKI
I have a problem with memory management when using a Perl
interpreter embeded in my application as described in perlembed. I'm not
sure if this is the right mailing list for this kind of question, but I
could not find a better one.
As a guess it's because the variables used within the eval aren't
dSP;
ENTER ;
SAVETMPS ;
PUSHMARK(SP);
//do you eval here
FREETMPS ;
LEAVE ;
and see if that makes a difference.
That solved the problem, thanks.
--
It's raisins that make Post Raisin Bran so raisiny ...

Eduardo M KALINOWSKI
***@bol.com.br
http://move.to/hpkb
Loading...