Archive for the tag: Java

Swing Hangs on Thread, Old Timers to Blame, Factory Fixes

Potential RPG 2 Comments »

Elderly swing-set factory employees using thread instead of chains forces product recall?

No. Why would you think that?

This article describes how the javax.swing.Timer utility can cause your Swing application to hang at shutdown, and how to fix it.

The Timer utility is useful for repeating tasks on the Swing/AWT thread. They’re handy enough to create in many places throughout GUI code. However, each one that remains active keeps the AWT thread alive, which prevents clean application shutdown (without resorting to System.exit()). Lacing the code with Timer instances makes it difficult to track them all down and stop them when the application is supposed to exit.

To correct the situation for the MMORPG client, I created a simple factory class with a create(..) method for producing Timer instances. The factory maintains a reference to every Timer created. At application shutdown, the factory’s stop() method is called, which tells each Timer to stop(). After replacing all Timer constructor calls with the factory’s create(..) method, the MMORPG client exits cleanly.

There are a few caveats. For one, you must be certain it is safe to stop Timers in this way (a Timer may be carrying out some critical pre-shutdown operation). In general, I only use Timers for GUI-related activities, and not to drive application logic. Another weakness is that the factory cannot guarantee the Timers will not be restarted, or that more timers will not be created, after stopping the factory. This could be guarded with a more sophisticated design, such as a TimerProxy class to prevent post-shutdown starting, refusing to create new timers after shutdown, or an isStopped() method for GUI code to query.

For the MMORPG client, this simple factory pattern is sufficient to untie Timers from the AWT thread, allowing clean shutdown without resorting to System.exit().

ProxyIcon

Developer's Cave, Potential RPG No Comments »

For those who enjoy design patterns, I’ve written a ProxyIcon for the MMORPG client. The reason is to decrease memory allocation in the client, which is due in large part to graphic images, under the theory that most are not needed most of the time. This article describes the ProxyIcon (implementation details are left as an exercise for the reader). First, there is already a central factory of Icons. So, integrating a new proxy pattern only involved changing the factory. ProxyIcon implements the javax.swing.Icon interface, so users are none the wiser.

ProxyIcon knows the source of the image to load. When any Icon methods are accessed, it makes sure the internal image is loaded. If not accessed for some timeout, the internal icon can be unloaded. The simplest implementation would have set the internal Icon reference to null, allowing the garbage collector to clean it up. Why the present perfect tense? Because there’s an even better approach:

ProxyIcon holds two references to the internal Icon: A hard reference and a soft reference. After the timeout, the hard reference is set null, but the soft reference is retained. Since the embedded icon is only referenced (never exposed) from the ProxyIcon object, this leaves only the soft reference. Java cleans up soft references (only) when memory is needed. If, however, the ProxyIcon is accessed before being cleaned up, the hard reference is reinstated. This provides the best of both worlds: Application logic can set policy on when to release resources but is backed up by the Java Virtual Machine’s garbage collection logic to avoid unhelpful cleanup.

The primary benefit, of course, is that unused icon resources can be deallocated. The software design benefit is that image users do not need to concern themselves with whether the icon is currently loaded or not. Notice that all ProxyIcon references stay in memory forever (in the factory). They could also be deallocated by using soft or weak references in the factory, but the objects themselves are (theoretically) miniscule compared to image memory consumption.

Another minor benefit is lazy image loading. Instead of loading upon construction, the internal icon is loaded lazily upon first access. There are a number of icons that are requested in the code, but not always used. This feature has the benefit that the code can greedily ask for icons from the factory (e.g., as static variables) without impacting memory if not needed.

One major gotcha is that Java itself may be holding cached references to the image data, which prevents garbage collection. I have not investigated this fully, but do not use Toolkit.getImage(), as it’s API warns of just this problem. Also read the code for javax.swing.ImageIcon, which makes (undocumented) use of Toolkit.getImage(). Instead, use Toolkit.createImage() or ImageIO.read() with ImageIO.setUseCache(false). Further investigation is needed to determine exactly who has access to underlying image data depending on how it is loaded.

For Alpha testers, look at $HOME/.potentialrpg/stat/IconFactory.stat, which shows:

timestamp, total, loaded, hard_referenced, average_ms_timeout, ms_stat_time

Graphic Processing Updates

Potential RPG No Comments »

Graphic processing in general has been radically improved. In addition, client memory footprint was
reduced by about 50% (then I enlarged the rendering area, bringing memory use back up). Here’s a lesson for Java image manipulation: use BufferedImage.TYPE_INT_RGB rather than BufferedImage.TYPE_INT_ARGB_PRE when possible (one variable increased world rendering performance by roughly 90%).

The client deadlock bug has been mitigated (read: not fixed yet, but less likely). The cause, for those who enjoy fables of thread contention, is the AWT thread holding the Content lock and awaiting the Render lock, whilst the rendering Engine held the Render lock and awaited the Content lock. The render process still needs the content lock on occasion. The real fix will involve changing the content update process to not hold its lock on event notification… but I digress.

For the player, you’ll notice a major improvement during the world shift (when you get near the edge of the minimap). This used to freeze the client for a few seconds (usually while you’re being pummeled by Ogres). There’s still a delay, but it’s more like 300ms. Also, there shouldn’t be any edge garbage on the minimap during the shift — you should immediately see new terrain to explore (as the edge terrain is now pre-rendered and ready for the shift).