Subject | URGENT: API memory leaks! |
---|---|
Author | Lev Assinovsky |
Post date | 2002-02-10T20:44:26Z |
Sorry for repost, I had some problem with registration in Yahoo.
We got the following problem (tested in IB6.01 and
FirebirdSS-1.0.0-0.Beta2 on
Linux).
Each nested SELECT allocates approx 24K - which is never returned.
I have a sample code which is big for the letter. Here's the
relevant section:
--------- cut here ------------------------------------
if (isc_dsql_allocate_statement(status, &DB, &stmt))
isc_print_status(status);
if (isc_dsql_allocate_statement(status, &DB, &stmt1))
isc_print_status(status);
if (isc_dsql_prepare(status, &trans, &stmt, 0, sel_str, 1, osqlda))
isc_print_status(status);
if (isc_dsql_execute(status, &trans, &stmt, 1, NULL))
{
ERREXIT(status, 1)
}
while ((fetch_stat = isc_dsql_fetch(status, &stmt, 1, osqlda)) == 0 {
/* Another select */
osqlda1 = (XSQLDA ISC_FAR*) malloc(XSQLDA_LENGTH(2));
osqlda1->sqln = 2;
osqlda1->sqld = 2;
osqlda1->version = 1;
osqlda1->sqlvar[0].sqldata = (char *)&col11;
osqlda1->sqlvar[0].sqlind = &flag0;
osqlda1->sqlvar[1].sqldata = col21;
osqlda1->sqlvar[1].sqlind = &flag1;
mall_st("Before prepare"); /*!!!!!!!!!!!!!!!!!*/
if (isc_dsql_prepare(status, &trans, &stmt1, 0, sel1, 1, osqlda1))
isc_print_status(status);
mall_st("After prepare"); /*!!!!!!!!!!!!!!!!!*/
if (isc_dsql_execute(status, &trans, &stmt1, 1, NULL))
{
ERREXIT(status, 1);
}
while ((fetch_stat = isc_dsql_fetch(status, &stmt1, 1, osqlda1)) ==
0)
{
}
if (fetch_stat != 100L)
{
ERREXIT(status, 1);
}
if (isc_dsql_free_statement(status, &stmt1, DSQL_close))
isc_print_status(status);
free(osqlda1);
}
---------- cut here --------------------
This 24K allocation happens at mall_st("After prepare") call - but in
the first
iteration only! Even if this section of the code is enclosed in the
infinite
loop - still 24K allocation happens only once ...
If this loop is duplicated, though - and top level select replace with
another one - then
memory would be allocated again.
There are two tables used in this example: big1 and big2. They have the
same
structure:
col1 integer not null primary key,
col2 varchar(200)
Funny enough - if big1 has 3 rows - memory is not allocated, but if
there are
100 rows - it is!
The way i caught this problem is - i have FastCGI application with 100
statement handles (tables), initialized on startup - which always stays
in memory. In a
week, memory used by this application grew from 1Meg to 6Meg.
My feeling is - the memory is allocated every time there's a new
(unique) pair
of SELECT statements. As you can easily see, this can
happen really frequently (100*100).
How do we deal with this problem?
Thanks in advance.
P.S. The following is the result of mal_st
in the 1st iteration:
Before prepare
Arena 0:
system bytes = 48336
in use bytes = 45944
Total (incl. mmap):
system bytes = 48336
in use bytes = 45944
max mmap regions = 0
max mmap bytes = 0
After prepare
Arena 0:
system bytes = 72912
in use bytes = 62344
Total (incl. mmap):
system bytes = 72912
in use bytes = 62344
max mmap regions = 0
max mmap bytes = 0
--
Lev Assinovsky Peterlink Web
Programmer St. Petersburg, Russia
Tel/Fax: +7 812 3275343 197022 ul.Chapigina 7а
E-mail: lev@...
We got the following problem (tested in IB6.01 and
FirebirdSS-1.0.0-0.Beta2 on
Linux).
Each nested SELECT allocates approx 24K - which is never returned.
I have a sample code which is big for the letter. Here's the
relevant section:
--------- cut here ------------------------------------
if (isc_dsql_allocate_statement(status, &DB, &stmt))
isc_print_status(status);
if (isc_dsql_allocate_statement(status, &DB, &stmt1))
isc_print_status(status);
if (isc_dsql_prepare(status, &trans, &stmt, 0, sel_str, 1, osqlda))
isc_print_status(status);
if (isc_dsql_execute(status, &trans, &stmt, 1, NULL))
{
ERREXIT(status, 1)
}
while ((fetch_stat = isc_dsql_fetch(status, &stmt, 1, osqlda)) == 0 {
/* Another select */
osqlda1 = (XSQLDA ISC_FAR*) malloc(XSQLDA_LENGTH(2));
osqlda1->sqln = 2;
osqlda1->sqld = 2;
osqlda1->version = 1;
osqlda1->sqlvar[0].sqldata = (char *)&col11;
osqlda1->sqlvar[0].sqlind = &flag0;
osqlda1->sqlvar[1].sqldata = col21;
osqlda1->sqlvar[1].sqlind = &flag1;
mall_st("Before prepare"); /*!!!!!!!!!!!!!!!!!*/
if (isc_dsql_prepare(status, &trans, &stmt1, 0, sel1, 1, osqlda1))
isc_print_status(status);
mall_st("After prepare"); /*!!!!!!!!!!!!!!!!!*/
if (isc_dsql_execute(status, &trans, &stmt1, 1, NULL))
{
ERREXIT(status, 1);
}
while ((fetch_stat = isc_dsql_fetch(status, &stmt1, 1, osqlda1)) ==
0)
{
}
if (fetch_stat != 100L)
{
ERREXIT(status, 1);
}
if (isc_dsql_free_statement(status, &stmt1, DSQL_close))
isc_print_status(status);
free(osqlda1);
}
---------- cut here --------------------
This 24K allocation happens at mall_st("After prepare") call - but in
the first
iteration only! Even if this section of the code is enclosed in the
infinite
loop - still 24K allocation happens only once ...
If this loop is duplicated, though - and top level select replace with
another one - then
memory would be allocated again.
There are two tables used in this example: big1 and big2. They have the
same
structure:
col1 integer not null primary key,
col2 varchar(200)
Funny enough - if big1 has 3 rows - memory is not allocated, but if
there are
100 rows - it is!
The way i caught this problem is - i have FastCGI application with 100
statement handles (tables), initialized on startup - which always stays
in memory. In a
week, memory used by this application grew from 1Meg to 6Meg.
My feeling is - the memory is allocated every time there's a new
(unique) pair
of SELECT statements. As you can easily see, this can
happen really frequently (100*100).
How do we deal with this problem?
Thanks in advance.
P.S. The following is the result of mal_st
in the 1st iteration:
Before prepare
Arena 0:
system bytes = 48336
in use bytes = 45944
Total (incl. mmap):
system bytes = 48336
in use bytes = 45944
max mmap regions = 0
max mmap bytes = 0
After prepare
Arena 0:
system bytes = 72912
in use bytes = 62344
Total (incl. mmap):
system bytes = 72912
in use bytes = 62344
max mmap regions = 0
max mmap bytes = 0
--
Lev Assinovsky Peterlink Web
Programmer St. Petersburg, Russia
Tel/Fax: +7 812 3275343 197022 ul.Chapigina 7а
E-mail: lev@...