Subclassing Graphics Class : Possible ?

Hi,

While looking for memory leaks in my application using a profiler, I just find out that the Graphics class was one of the problem !

The methods Graphics.hitClip() and Graphics.getClipBounds® are creating a huge amount of Rectangle objects. These methods are called from the paintchildren() of JComponent.

The distressing part is the comment I found in the Graphics class source code in the hitClip() method :


public boolean hitClip(int x, int y, int width, int height) 
{
   // Note, this implementation is not very efficient.
   // Subclasses should override this method and calculate
   // the results more directly.
   Rectangle clipRect = getClipBounds();
   if (clipRect == null) {
        return true;
   }
   return clipRect.intersects(x, y, width, height);
}

How do we subclass the Graphics class ?

The only information I found so far was the following class hierarchy :

[]public java.lang.Object
[
]public abstract java.awt.Graphics
[]public abstract java.awt.Graphics2D
[
]public abstract sun.java2d.SunGraphics2D
[*]public sun.awt.windows.WGraphics

There are way too many abstract methods to implement in the Graphics class…

My Goal is to optimize the Graphics class for less Rectangle object creation ? Any ideas ?

Thanks,

Philippe

You can’t achieve anything by attempting to subclass Graphics. You have to change the way you use it instead. Is the creation of these rectangles actually costing you a significant amount of time — short lived objects are usually quite cheap?
If these objects are mostly created within Swing, then to estimate the time taken just create some more in your own paint code and measure the effect on the total paint time.

You’re not supposed to subclass Graphics class . That comment is for our internal implementation.

What are the cases where you see a lot of objects being created? Why do you think it’s a bottleneck? Rectangle is a tiny object, it’s allocation/deallocation happens in young generation and is virtually free.

Also,which jdk version are you using?
What platform?

Hi,

Thanks for your answer !

I am using jdk1.3.1 under Windows 2000 with a Pentium 2.4ghz with 1gig Ram.

My application is a 2D equipment simulator composed of switches, toggles and leds. All my components are based on a generic class that is a JPanel on which I can draw back images. All the components are placed in a layered fashion and the top component window is a JFrame.

The memory problem I have was reported by the OptimizeIt profiler during a repaint operation where many leds (50) were flashing at the same time. It looks like the sunGraphics2D.transformShape() method is the one allocating the most Rectangles, followed by the graphics.hitclip() method (the overall Rectangle object allocation is around 2 megs/sec !) .

OptimizeIt screeenshot:
NOT AVAILABLE

So, my question is, there must be a way to limit the amount of Rectangle generated by the repaint operation ?

PS : I also tried to subclass the Graphics class, and I clearly saw that it was not meant to be subclassed because a lot of the double buffering mechanism was bypassed.

Phil

You haven’t provided any evidence that the Rectangle creation is costing much time (attempting to profile it may distort the result).
How many components do you have on your panel?

Hi,

I have around 50 leds flashing on my screen.

As you can see on the OptimizeIT graph, the GC activity is pretty high and you can see the memory usage growing up and down in a periodic manner.

Image:
NOT AVAILABLE

So, the main problem seems to be the high amount of Rectangle creation, followed by a high GC activity.

Does anyone have seen this kind of excessive Rectangle object creation before ?

Thanks,

Philippe

We don’t doubt that lots of rectangles are being created, just that this activity is costing much time. It is tricky to accurately time this activity, hence my suggestion of creating even more rectangles. Please note that attempting to time rectangle creation (and related GC costs) directly will almost certainly fail to produce a meaningful result.

I think it is pretty clear that when we try to measure the performance of an application in terms of speed of execution, there are a lot of errors generated by the probing method we are using to get the data. This is a basis of performance analysis.

I think that the problem I am experiencing is not in that area : the problem seems to be related to the high amount of short life object created (mainly Rectangles) periodically. I am only talking about memory usage, and not speed of execution (even though any excessive temporary object allocation will lead to high GC).

Then try changing the size of the new generation (“eden space” IIRC?) - making this space big enough should make those rectangle (de)allocations virtually free (gc only increase’s a pointer index - no allocation/deallocation - very fast).

Also, any chance you can try your application on latest jdks? 1.4.2, for example? We’ve made a lot of work in 1.4 to eliminate unnecessary object creation.