Random graphics slowdowns

Hi,

I’m not sure if this is the right place to post a message like this, but I’m out of ideas.

I have a problem with an application I am developing, it’s fairly complex with the possibility of having many windows open at once. Some may be drawing vector graphics some may be using raster graphics some may just be displaying ordinary swing components, all updating at the same time.

The problem seems to be that very occasionally when one of the raster windows is open, the time taken for it’s paintComponent() method goes through the roof. It suddenly jumps from taken a few tens, maybe 100 milliseconds to taking three seconds to draw a few updates. The trouble is it’s very intermittent and I’ve never managed to get it to happen when running in a profiler, so I can’t tell exactly what line is the problem (or even if it is as simple as that). The result of this is that the whole GUI becomes very unresponsive until the offending window is closed, opening it up again (which recreates it from scratch) after a couple of minutes seems to solve the problem.

The window is using MemoryImageSources and VolatileImages to draw. I think what is happening is that either there is some excessive object creation and so there is a lot of garbage collection going on, or the event queue is becoming flooded with pending events and not keeping up. The thing is, surely both of these possibilities should be reasonably reproducable.

I know it’s a long shot, but has anyone here seen anything like this before? What could cause the same code to suddenly take so much longer to execute?

Alex

hi! this is someething very usual with GUI’s . Swing gets overfloed if the repaint mathod iss called when repainting hasn’t yet finishd, that is, when your paintComponent’s takes more than expected time to complete. Usually Swing tutorials suggest to have its events methods impl. so that they return quickly.
The general solution is to synchronize on your component so that it cannot execute multiple Threads on it. Therefore a more attentive selection of what and how much threads call the update process must be cared to. Caution is to using the EDT (events listener impl.) when you have such complex vetorial or pictured components. ;D

The trouble is the paintComponent() method usually executes very quickly, but then suddenly, for no reason I can find, it starts to take very much longer. Also, I’m pretty sure that only one thread will be calling the repaints on the component that seems to be causing the problem. Other components will be being updated by other threads, but that shouldn’t be causing this.

Maybe you could try switching to a regular BufferStrategy and see what happens.

Alternately, it could be an issue with some of your images not being accelerated, assuming that you are drawing images. That would only be the case if the images you’re drawing are changing when the problem occurs.

I once had this problem after switching between 2 screens and fixed it by making sure that the status screen (or whatever it was) that was being drawn to a BufferedImage wasn’t being drawn to an accelerated BufferedImage. This fixed the problem. The other images were no longer being accelerated because the giant status screen image was even though it didn’t need to be.

One of the possibilities that I had though of was that the images that had been hardware accelerated suddenly were not because the video memory was full, but surely that would be reproducible by opening lots of windows, and this doesn’t seem to be that case. I’ll try it again though just to see.

I’m not sure that a BufferStrategy makes any difference, I’m pretty sure that we tried it before, and if anything it was slower. I’ll try again to be sure.

The images need to be hardware accelerated to get the required performance. The trouble is the Matrox Parhelia and QID cards we’re using are a bit pathetic! The point about unnecessarily accelerating images that don’t need to be is an interesting one as I do have a large static off screen BufferedImage that could be using a lot of video memory when it shouldn’t, I’ll check whether it is or not.

Thanks for the suggestions

Alex

Though this is not very easy to figure out without an actual code, there’s much to say about Threading multiple components together. In fact, most of the topic is about how quick or how many Threads are executing simultaneously.
Merely, it is realy important to keep in mind that each Thread instanciated allocates new resources for each new instance, that is, a buffer array is allocated for each Image instanciated. If the paintComponent uses doubleBuffering as it is often the case, 3 Threads or 3 loops over the method will cause 3 buffers allocated at the same time. Then it’s up to the class object to make sure the SAME BUFFER IS REUSED EVERYTIME, or at least clered before it is repainted.

When talking about slowdowns, we must pay pretty much more attention to the amount of NEW MEMORY ALLOCATIONS are made at each loop. This is quite simple to mesurate with a simple debug-tool that can be found in every JAVA IDE.
Actually, Java gets slow when it has too much stuff to delegate to its Garbage Collector (aka GC). Afterwards, you should know that a repaint() call may take a few time to complete unlike a (BufferStrategy).show() will complete immediately. Swing has also implemented for each of their HeavyWeight components a paintImmediately() method that provides IMMEDIATE REFRESH.

Up to you to choose passive or active rendering, up to you to focus on multi-threading or single-threading. :smiley:

A easy to make mistake with swing is to midify that component or even request its redraw from within a swing event. Such as actionPerformed. Make suere you are not requesting the repain from that event it will be delayed or even not happen :S

Rather use the runable interface and post the code that asks for the repaint cahnges the display to swing to be executed after all events.

I am not sure if this is what you are doing but make sure you not asking for a repain from within a swing event.

Thanks for the replies,

The repaint() is being called from a timer task and so is not being called from the event thread, but surely that might cause problems with when painting happens rather than suddenly slowing down.

I’ve used both OptimizeIt and the Netbeans profiler in trying to track down this problem, the trouble is I’ve never managed to replicate the problem when running in the profiler.

When everything is painting correctly and performance is good, there is no excessive garbage collection going on (the time spent in GC barely registers in the netbeans profiler), but I haven’t been able to tell what changes when everything slows down. Also there is no memory leak, even after running for an entire weekend the memory usage had barely changed.

I have made a change to make sure that a large image that is loaded into memory that doesn’t require high performance is not being loaded into video memory by using setAccelerationPriority(0), does this actually do anything!? I’m wondering if I’m running out or video memory and some images that has been accelerated are suddenly not anymore. Does this sound likely?

Alex

Actually, I think there’s some method for checking how much video memory you have left, but I can’t recall what it is. If you can find the method, you can use it to check this out.

It’s probably in the GraphicsDevice class or something.

I’d try not calling repaint from a timer task like they suggested.

Use getAvailableAcceleratedMemory() but take care, it doesn’t work in my case, it always returns 0, I don’t know why.

The problem is not due to the video memory being filled because I tried finding out how many windows my application needs to open before images stop being created in video memory. I run out of stack space before I run out of video memory, and I have to have an insane number of windows open to do it.

I tried getAvailableAcceleratedMemory() but it returns the sum of the available video memory, plus the amount of system memory that can be used for textures. So I get 600Mb free on a 128Mb video card!!!

In the end I used the Caps Viewer utility from the DirectX SDK to find the actual amount of memory free on the video card, and as I said I don’t think that running out of video memory is causing this random slowdown

PS fletchergames what do you mean by “I’d try not calling repaint from a timer task like they suggested.”. I’m using a timer task to make sure that the performance is deterministic (this was a change made in trying to solve this slowdown problem), it’s not calling repaint from the Swing thread

[quote=“ajh499,post:11,topic:30838”]
I thought you said that the repaint method was being called from the AWT event thread, when you said that it was not. So never mind. My comment was in error.

Hi all !
Big update is not big changes. I’ve looked out on the web for some information about dead-locks and slowdowns with Java2 and its latest updates. The more I could imagine is that some updates would make things go nicer but not faster. In facts, there’s a big problem with the JFileChooser and Windows XP running java 2 release 6. Yes, swing stuff looks smarter and prettier but the slowdown with Swing is sensible on some low-end processors.
Therefore I contacted a Sun developer about that, it was on the last Launch4J release that got stuck for several seconds till whole 5 minutes to find my files on desktop. :-[ What he answered was that it’s a known bug with Java 2 release 6. So do I understand that java 6 is bugged ? Quite not so far, indeed I get back my Java 2 release 5 SE on top and deleted 6th release where my desktop remained reactive yet !
So be careful if you use the new features of Java 6 because Java 5 still brings out the BEST of Java on ALL PLATFORM, OS X in particularity and the Swing slowdowns on XP desapear. ::slight_smile:

I have experienced a somewhat similar problem, where I could not reproduce the problem while profiling. It was not directly gfx related, but rather a multithreading issue. The profiling slowed down the execution enough that the problem never was triggered. I figured it out after I had added debug logging and spotted a pattern in the creation order when it failed.

Good luck

Hmm,

We are using Java 5 so it’s not a bug introduce in Java 6.

I can’t reproduce the problem reliably when running normally, let alone in the profiler. I think it must be some sort of threading issue, but I’ve no idea what it might be.

Sometimes the drawing may slow right down even though there are very few windows open, and then at other times there may be many more windows open and everything runs fine.

???

Alex

There are similar problems with my application running java 5 or 6 config : 2600+ Sempron integrated AMD chipset with S3 graphics on shared memory 768Mo RAM and Windows XP servicepack 2. Another higher-end config works ok : Celeron D 2.8 w/ Radeon 9250 Graphics card 128Mo dedicated memory and 1024Mo RAM Windows XP servicepack 2. :o
So what’s the deal ? Does shared memory implies poor graphics support w/ Java ? Java 5 brings out the best results on both platforms but the double-buffered graphics fail w/ the low-end configs.
What are your configuration specs ? ::slight_smile:

I’m running on a dual-core Pentium D 930, 2Gb RAM and a either a Matrox Parhelia or a Matrox QID quad-head card. The Matrox cards are a bit hopeless really!! I’d suspect that the problem is somehow related to the Matrox carrds as the problem does not seem to be as common on less powerful machines with better graphics cards.

I’ve just bought a graphics card to upgrade from integrated “poor” S3 graphics with an ATI Radeon. It can now load Direct3D accelaration but no JAI/JIIO natives are supported. Hence, my application is too slow disabling JIIO natives to go up to 15FPS. Plus, java 6 on Windows XP is really bugged. Got back to Java 5 everything works but graphics are not ok. I’m wondering about upgrading that station to a minimal 1GB RAM storage, because it is currently only 768MB which seem not to succeed. :o

Plus, java 6 on Windows XP is really bugged.
Well here the experiences seem to differgence - for me Java6 was the best java-release ever.
Which problems do you have, maybe it can be worked on?

lg Clemens

hi!
here’s one of the most annoying bug reported everywhere, it’s about FileChooser : http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6578753
of course, on high-end systems it does not appear clearly but on one of my station, which has AMD and less than 1GB RAM, the issue is a bit annoying, so did I got back to release 5.