[gdal-dev] Re: JAVA API - Performance

Simone Giannecchini simone.giannecchini at geo-solutions.it
Tue Nov 24 18:58:41 EST 2009


Ciao Even,
please read below...
-------------------------------------------------------
Ing. Simone Giannecchini
GeoSolutions S.A.S.
Founder - Software Engineer
Via Carignoni 51
55041  Camaiore (LU)
Italy

phone: +39 0584983027
fax:      +39 0584983027
mob:    +39 333 8128928


http://www.geo-solutions.it
http://geo-solutions.blogspot.com/
http://simboss.blogspot.com/
http://www.linkedin.com/in/simonegiannecchini

-------------------------------------------------------



On Fri, Nov 20, 2009 at 7:46 PM, Even Rouault
<even.rouault at mines-paris.org> wrote:
> Hi Simone,
>
> Simone Giannecchini a écrit :
>>>
>>> I've tried GetPrimitiveArrayCritical() / ReleasePrimitiveArrayCritical()
>>> and
>>> I've observed they return non-copy pointers, which make them good
>>> candidates.
>>> Looking at
>>>
>>> http://java.sun.com/j2se/1.3/docs/guide/jni/jni-12.html#GetPrimitiveArrayCritical,
>>> it appears that there are restrictions to use them. But this is probably
>>> OK as
>>> we don't callback Java code in the RasterIO operations. But I'm not sure
>>> if the
>>> native operation can be considered to be fast enough to use those
>>> primitives. It
>>> depends on the query size and the driver. Perhaps it is not worth the
>>> risk and
>>> that the copy made by the JVM when calling GetByteArrayElements() is not
>>> that
>>> significant for modest size arrays.
>>
>> I decide not to take the risk. The problem with that call is that It
>> should block the GarbageCollector and this is highly counterproductive
>> in server side application (you tend to prefer less pause times more
>> often than  a long pause time once ia while).
>>
>>
>
> I didn't use it finally. Just regular
> Get(Byte|Short|Int|Float|Double)ArrayElements functions.
>
>>> Another possibility is that in the ReadRaster() case, we don't care about
>>> the
>>> initial values of the array. We just want to update it in fact, so we
>>> could
>>> allocate a working buffer in the JNI code, call the native RasterIO() on
>>> it and
>>> upload its content into the Java array with SetByteArrayRegion(). This
>>> would
>>> save one copy.
>>>
>>
>> For the reasons I said in my previous email I would refrain from
>> allocating raster data inside the native code, the JVM seems to not
>> like that too much.
>> Moreover, the Java flag to control the native memory space is prefixed
>> XX which means that it might stop orking with no notice in a newer
>> java release.
>> I guess that the best thing, IMHO, is to stick with pinning and hope
>> for the best, however, it might be interesting to do kind of a testing
>> session having the geoserver hitting the gdal code for something like
>> ECW and see what happens with the different options in term of
>> stability/performance/robustness, what do you think?
>>
>>
>
> I did use the temporary allocation of a buffer before calling RasterIO() and
> then updating the Java array with
> SetByteArrayRegion(). I'm not sure why the JVM wouldn't like that. It
> doesn't have to deal with memory
> allocations done by third-party code and I'm working daily with a Java app
> that uses native DLLs that allocates
> big amount of memory without any problems. If a JVM doesn't like that, I
> would consider it to be seriously broken
> (that would imply that GDAL can't do its own memory allocations either and
> it must allocate temporary buffers for its
> block cache for example...).

Here what we have been facing during the performance shootout for the
FOSS4G for ECW data served via GDAL with GeoServer.
Under high load the GeoServer  was crashing the JVM with a strange
error unrelated to GDAL or GeoServer itself. The Java2D rendering
pipeline was dying on a null pointer exception since medialib was
unable to allocate internal intermediate images and apparently no
check against this conditions was made hence the crashes.

Now why this was happening and why we tried to move away from
DirectBuffers. My understanding of the memory model in Java is that
you roughly have two spaces one handled by the JVM (heap, stack on so
on) and then the native space, where the native code (e.g. GDAL)
allocates his memory and which is use by the JVM internal code itself
for his memory (and by the DirectMemory itself). Our guess was that
under real heavy load the couple GeoServer+GDAL using DirectBuffers
was exhausting the native memory of the JVM process jeopardizing the
JVM itself. Once we moved away from the DirectBuffers we got no more
problems.

Simone.

> However if you observe that it is a problem,
> you could try changing the typemaps to use
> the regular array pinning (it's the /* %typemap(in, numinputs=1) (ctype
> *regularArrayOut, long nRegularArraySizeOut)  */
> around line 1400 in swig/include/java/typemaps_java.i) to see if it changes
> things.
>
> I'd be happy to hear about the results of your tests with Geoserver.
>
> Even
>
> _______________________________________________
> gdal-dev mailing list
> gdal-dev at lists.osgeo.org
> http://lists.osgeo.org/mailman/listinfo/gdal-dev
>


More information about the gdal-dev mailing list