Even,
I opened a ticket in GDAL Trac: http://trac.osgeo.org/gdal/ticket/4749.
Thank you,
Pierluigi
Il 13/07/2012 12.14, Even Rouault ha scritto:
Selon Pierluigi Guasqui <[email protected]>:
Hello,
I am experiencing a big memory allocation (with no subsequent memory
release) when using SQL queries with shapefiles. This is a sample code
that triggers this problem:
OGRRegisterAll();
// opening shapefile data source
const char *fname = "path/to/shapefile.shp";
OGRDataSource *poDS;
poDS = OGRSFDriverRegistrar::Open( fname, FALSE );
if( poDS == NULL )
{
fprintf( stderr, "%s: could not open input file\n", fname );
return -1;
}
// creating the spatial filter
OGRLineString regionPolygon;
OGRRawPoint *pointsList = new OGRRawPoint[5];
pointsList[0].x = -180; pointsList[0].y = 90;
pointsList[1].x = 180; pointsList[1].y = 90;
pointsList[2].x = 180; pointsList[2].y = -90;
pointsList[3].x = -180; pointsList[3].y = -90;
pointsList[4].x = -180; pointsList[4].y = 90;
regionPolygon.setPoints(5, pointsList);
delete[] pointsList;
// executing the query
const char *query = "SELECT * FROM table_name WHERE some_field
LIKE
'%bla%' ORDER BY some_other_field";
OGRLayer *rs = poDS->ExecuteSQL( query, ®ionPolygon, NULL );
// releasing memory
poDS-> ReleaseResultSet( rs );
OGRDataSource::DestroyDataSource( poDS );
With a 100.000 records shapefile "ExecuteSQL" has allocated over 300
MBytes of memory with no deallocation when calling "ReleaseResultSet".
The memory leak is triggered only when "ExecuteSQL" is called with a
spatial filter (even trivial as shown in the above code) and the SQL
query contains a 'WHERE' clause and an 'ORDER BY' clause. Is this a
bug?
I am using GDAL 1.9.1 under Windows platform.
Any help would be really appreciated!
Pierluigi,
I have not a dev environmenet at the moment to investigate that, but
could you
open a ticket in GDAL Trac with all the details so it does not get
lost ?
Are you positive that, all other things unchanged, the presence of
the spatial
filter makes a difference ? I'm not sure how you check on Windows if
the memory
is really released (if you put your code in a while(1) {} loop, does
the memory
used by the process increase at each iteration ?).
I also suspect that your spatial filter will not do what you would
(probably)
expect from it. The geometry of the filter is a LINESTRING, not a
POLYGON. So it
will only filter geometries that intersect the line, not geometries
that are
fully inside it.
Best regards,
Even
Even,
thank you for looking into my problem and for your reply. Yes I will
open a ticket in GDAL Trac.
I tried different test cases so I am sure that If I leave all other
things unchanged and just remove the use of the spatial filter I do
not see any memory leak. So it seems that the use of the spatial
filter does make the difference. Also, I tried the SQL query without
the "WHERE" clause or the "ORDER BY" clause and, again, I did not see
any memory leak. So also the use of "WHERE" clause *and* "ORDER BY"
clause seem to make the difference.
To check on Windows that memory is not released I put a "Sleep()" call
by the end of my code so I could check with Task Manager the process
memory allocation before the process quits. However, I added a
while(true) loop around my previous code:
OGRRegisterAll();
int loop_i = 1;
while ( true )
{
fprintf( stdout, "*** Loop %d... ", loop_i++ );
fflush( stdout );
// opening shapefile data source
const char *fname = "path/to/shapefile.shp";
OGRDataSource *poDS;
poDS = OGRSFDriverRegistrar::Open( fname, FALSE );
if( poDS == NULL )
{
fprintf( stderr, "%s: could not open input file\n", fname );
return -1;
}
// creating the spatial filter
OGRLineString regionPolygon;
OGRRawPoint *pointsList = new OGRRawPoint[5];
pointsList[0].x = -180; pointsList[0].y = 90;
pointsList[1].x = 180; pointsList[1].y = 90;
pointsList[2].x = 180; pointsList[2].y = -90;
pointsList[3].x = -180; pointsList[3].y = -90;
pointsList[4].x = -180; pointsList[4].y = 90;
regionPolygon.setPoints(5, pointsList);
delete[] pointsList;
// executing the query
const char *query = "SELECT * FROM table_name WHERE some_field
LIKE '%bla%' ORDER BY some_other_field";
OGRLayer *rs = poDS->ExecuteSQL( query, ®ionPolygon, NULL );
// releasing memory
poDS-> ReleaseResultSet( rs );
OGRDataSource::DestroyDataSource( poDS );
fprintf( stdout, "done\n" );
fflush( stdout );
}
and I could get my process to allocate almost 1 GBytes of memory in
just 3 loops! So, yes memory keeps on being allocating without being
released at each iteration.
Related to the use of LINESTRING filter instead of a POLYGON filter,
yes you are right: it will filter out features that intersect my line
but this is what I expect from the code from which I extrapolated the
example above. However, thank you for warning me!
Thank you!
--
Pierluigi Guasqui
Applied Coherent Technology Corp.
_______________________________________________
gdal-dev mailing list
[email protected]
http://lists.osgeo.org/mailman/listinfo/gdal-dev