(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
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