(original) (raw)

Dear java2d members,

FYI: I now have a working patched java2d pisces that performs better: no memory waste (99%) and performance increased on complex operations (dashed ...); patch / benchmark in progress ...


Does J2DBench have a regression test mode ?
i.e. capture screenshots (with few shapes) to compare them between different runs (image comparison pixel by pixel)

Besides, I found an important bug in pisces Stroker / Dasher: it does not use the clip region given to PiscesRenderingEngine.getAATileGenerator(clip).


In Aspro2, I can zoom on jFreeChart plots a lot and it draws shapes (rectangle or lines with dashed lines) then the dasher emits segments out of the visible area (millions in case of a important zoom) and the application hangs a for while (5s to minutes).


I would like to determine the shape part (line or any complex shape) that is inside the clip and avoid useless segments (Stroker / Dasher).

Does somebody have any idea ?
or know java2d.pisces code enough to help me ?


Laurent


2013/3/26 Laurent Bourg�s <bourges.laurent@gmail.com>

Dear all,

First I joined recently the openJDK contributors, and I plan to fix java2D pisces code in my spare time.

I have a full time job on Aspro2: http://www.jmmc.fr/aspro; it is an application to prepare astronomical observations at VLTI / CHARA and is very used in our community (200 users): it provides scientific computations (observability, model images using complex numbers ...) and zoomable plots thanks to jFreeChart.


Aspro2 is known to be very efficient (computation parallelization) and I am often doing profiling using netbeans profiler or visualVM.

To fix huge memory usages by java2d.pisces, I started implementing an efficient ArrayCache (int[] and float[]) (in thread local to concurrency problems):

- arrays in sizes between 10 and 10000 (more small arrays used than big ones)
- resizing support (Arrays.copyOf) without wasting arrays
- reentrance i.e. many arrays are used at the same time (java2D Pisces stroke / dash creates many segments to render)

- GC / Heap friendly ie support cache eviction and avoid consuming too much memory

I know object pooling is known to be not efficient with recent VM (GC is better) but I think it is counter productive to create so many int[] arrays in java2d.pisces and let the GC remove such wasted memory.


Does someone have implemented such (open source) array cache (core-libs) ?
Opinions are welcome (but avoid "trolls").

Moreover, sun.java2d.pisces.Helpers.widenArray() performs a lot of array resizing / copy (Arrays.copyOf) that I want to avoid mostly:

��� // These use a hardcoded factor of 2 for increasing sizes. Perhaps this
��� // should be provided as an argument.

��� static float[] widenArray(float[] in, final int cursize, final int numToAdd) {
������� if (in.length >= cursize + numToAdd) {

����������� return in;
������� }

������� return Arrays.copyOf(in, 2 * (cursize + numToAdd));
��� }


��� static int[] widenArray(int[] in, final int cursize, final int numToAdd) {

������� if (in.length >= cursize + numToAdd) {
����������� return in;

������� }
������� return Arrays.copyOf(in, 2 * (cursize + numToAdd));

��� }

Thanks to Peter Levart, I use its microbench tool (https://github.com/plevart/micro-bench/tree/v2) to benchmark ArrayCache operations... and J2DBench to test java2d performances


...

PS: java.awt.geom.Path2D has also memory allocation issues:

������� void needRoom(boolean needMove, int newCoords) {

����������� if (needMove && numTypes == 0) {
��������������� throw new IllegalPathStateException("missing initial moveto "+

��������������������������������������������������� "in path definition");
����������� }

����������� int size = pointTypes.length;
����������� if (numTypes >= size) {

��������������� int grow = size;
��������������� if (grow > EXPAND_MAX) {

������������������� grow = EXPAND_MAX;
��������������� }

��������������� pointTypes = Arrays.copyOf(pointTypes, size+grow);
����������� }

����������� size = floatCoords.length;
����������� if (numCoords + newCoords > size) {

��������������� int grow = size;
��������������� if (grow > EXPAND_MAX * 2) {

������������������� grow = EXPAND_MAX * 2;
��������������� }

��������������� if (grow < newCoords) {
������������������� grow = newCoords;

��������������� }
��������������� floatCoords = Arrays.copyOf(floatCoords, size+grow);

����������� }
������� }


Best regards,
Laurent