GUI Freeze D3D Screen Updater thread blocked
Hi All, I have a GUI with a JTable event log that is updating about once a second and the GUI freezes randomly after a period of time. I have only recently started running the GUI on a PC using windows 7 running JRE 1.7, previously on XP running JRE 1.6 I did not see this problem.
Initially it looked like the problem was due to calls to swing operations to scroll the parent JScrollPane to the last event within the event listener method were not being run on the AWT EventThread. So I added the following code to the eventPosted method to force execution of the swing operations on the AWT EventThread:
Code :
SwingUtilities.invokeLater(new Runnable() {
public void run()
{
try
{
scrollToBottom();
}
catch(Exception e)
{
e.printStackTrace();
throw new RuntimeException(e);
}
}
});
private void scrollToBottom()
{
Dimension dim = scrollPane.getViewport().getViewSize();
Point curr = scrollPane.getViewport().getViewPosition();
curr.translate(0, (int)dim.getHeight());
scrollPane.getViewport().setViewPosition(curr);
eventTable.revalidate ();
}
but I still get the random lockups. After a lock-up here's a snipet of the jstack output from the process:
D3D Screen Updater" daemon prio=8 tid=0x000000000a848800 nid=0x7e8 waiting for monitor entry [0x000000000b1ff000]
java.lang.Thread.State: BLOCKED (on object monitor)
at java.awt.Window.getOpacity(Window.java:3519)
- waiting to lock <0x00000000c1d2ad80> (a java.awt.Component$AWTTreeLock)
at sun.awt.SunToolkit.isContainingTopLevelTranslucent (SunToolkit.java:2018)
at sun.awt.windows.WComponentPeer.isAccelCapable(WCom ponentPeer.java:1030)
at sun.java2d.d3d.D3DSurfaceData$D3DWindowSurfaceData .restoreSurface(D3DSurfaceData.java:938)
at sun.java2d.d3d.D3DScreenUpdateManager.validate(D3D ScreenUpdateManager.java:491)
at sun.java2d.d3d.D3DScreenUpdateManager.run(D3DScree nUpdateManager.java:466)
at java.lang.Thread.run(Thread.java:722)
"AWT-EventQueue-0" prio=6 tid=0x0000000007c4e000 nid=0x1a5c in Object.wait() [0x000000000a7cd000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00000000c1b98c80> (a java.lang.Object)
at java.lang.Object.wait(Object.java:503)
at sun.java2d.d3d.D3DScreenUpdateManager.runUpdateNow (D3DScreenUpdateManager.java:419)
- locked <0x00000000c1b98c80> (a java.lang.Object)
at sun.java2d.d3d.D3DBlitLoops.IsoBlit(D3DBlitLoops.j ava:352)
at sun.java2d.d3d.D3DRTTSurfaceToSurfaceBlit.Blit(D3D BlitLoops.java:439)
at sun.java2d.pipe.DrawImage.blitSurfaceData(DrawImag e.java:956)
at sun.java2d.pipe.DrawImage.renderImageCopy(DrawImag e.java:578)
at sun.java2d.pipe.DrawImage.copyImage(DrawImage.java :71)
at sun.java2d.pipe.DrawImage.copyImage(DrawImage.java :1011)
at sun.java2d.pipe.ValidatePipe.copyImage(ValidatePip e.java:186)
at sun.java2d.SunGraphics2D.drawImage(SunGraphics2D.j ava:3062)
at sun.java2d.SunGraphics2D.drawImage(SunGraphics2D.j ava:3047)
at javax.swing.RepaintManager$PaintManager.paintDoubl eBuffered(RepaintManager.java:1484)
at javax.swing.RepaintManager$PaintManager.paint(Repa intManager.java:1413)
at javax.swing.RepaintManager.paint(RepaintManager.ja va:1206)
at javax.swing.JComponent.paintForceDoubleBuffered(JC omponent.java:1090)
at javax.swing.JViewport.paintView(JViewport.java:160 9)
at javax.swing.JViewport.windowBlitPaint(JViewport.ja va:1540)
at javax.swing.JViewport.setViewPosition(JViewport.ja va:1092)
at javax.swing.ViewportLayout.layoutContainer(Viewpor tLayout.java:199)
at java.awt.Container.layout(Container.java:1503)
at java.awt.Container.doLayout(Container.java:1492)
at java.awt.Container.validateTree(Container.java:168 8)
at java.awt.Container.validateTree(Container.java:169 7)
at java.awt.Container.validate(Container.java:1623)
- locked <0x00000000c1d2ad80> (a java.awt.Component$AWTTreeLock)
at javax.swing.RepaintManager.validateInvalidComponen ts(RepaintManager.java:653)
at javax.swing.RepaintManager$ProcessingRunnable.run( RepaintManager.java:1620)
at java.awt.event.InvocationEvent.dispatch(Invocation Event.java:251)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.j ava:705)
at java.awt.EventQueue.access$000(EventQueue.java:101 )
at java.awt.EventQueue$3.run(EventQueue.java:666)
at java.awt.EventQueue$3.run(EventQueue.java:664)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPri vilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java: 675)
at java.awt.EventDispatchThread.pumpOneEventForFilter s(EventDispatchThread.java:211)
at java.awt.EventDispatchThread.pumpEventsForFilter(E ventDispatchThread.java:128)
at java.awt.EventDispatchThread.pumpEventsForHierarch y(EventDispatchThread.java:117)
at java.awt.EventDispatchThread.pumpEvents(EventDispa tchThread.java:113)
at java.awt.EventDispatchThread.pumpEvents(EventDispa tchThread.java:105)
at java.awt.EventDispatchThread.run(EventDispatchThre ad.java:90)
It looks like a race condition where the AWT Queue thread has the AWTTreeLock and then has kicked the D3D Screen Updater to update the screen but fails to return because its also waiting on the same component AWTTreeLock.
Any ideas why I should be seeing this?
Re: GUI Freeze D3D Screen Updater thread blocked
Can you post an SSCCE that demonstrates the problem? Are you making changes to the GUI on a non-EDT thread? If so, don't do that.
Re: GUI Freeze D3D Screen Updater thread blocked
The event table is part of a large GUI so its not easy for me to reproduce via a SSCCE. From the stack trace I don't see any obvious GUI changes occurring on non-EDT threads just after the lock-up. How would you recommend analyzing the code to determine if other threads are performing swing operations? Are there any good tools for this? Thanks in advance for any advice.
Re: GUI Freeze D3D Screen Updater thread blocked
Without an SSCCE, it's going to be pretty hard to help you debug the problem. But I will say that the stack trace won't necessarily include non-EDT threads, since the problem might be caused on another thread but only show up when the EDT correctly calls the gui code.
You should never make changes to the gui from a non-EDT thread. There are methods in the SwingUtilities class that might help you narrow down the problem.
Re: GUI Freeze D3D Screen Updater thread blocked
Disabling the Direct3D Pipeline using the following property -Dsun.java2d.d3d=false seems to have resolved my problem.
The legacy GUI I'm supporting does make changes from non-EDT threads all over the place, so there's more work to do but this consistent lock-up seems to have gone away with the disabling of the D3D Screen Updater thread that I don't think is needed for a standard swing GUI (works ok without it).
Did also notice that their have been problems in this area:
Bug ID: 6607230 D3D: infinite wait is possible in D3DScreenUpdateManager.runUpdateNow()
Thanks for the advice.