Java Swing 显示停止更新,直到生成 X 事件
编辑:最后的附加信息
我有一个(大型)Java Swing 应用程序,它演示了一些非常奇怪的行为。如果运行它的计算机闲置(没有鼠标或键盘输入)足够长的时间(从一小时左右到几天不等),Swing 显示有时会完全停止更新(我们有,除其他外) ,屏幕上显示的时钟停止更新),直到用户移动鼠标。移动鼠标后,我们的应用程序似乎可以正常运行。 (从另一个应用程序创建和删除窗口也会导致显示再次开始更新;键盘输入似乎不够。)
我们在 Linux 内核 2.6.25.14 上运行 Sun 的 JDK 1.6.0_07(我认为这是一个修改版 ) RHEL 4 发行版,但我不确定)运行 xorg-x11-server 1.1.1-48.13.e15。
当处于这种状态时,AWT 事件队列始终是“可运行的”,并且在几个 java2d 方法之一中 - 我最近的示例是:
at sun.java2d.loops.Blit.Blit (native method)
at sun.java2d.pipe.DrawImage.blitSurfaceData
at sun.java2d.pipe.DrawImage.renderImageCopy
at sun.java2d.pipe.DrawImage.copyImage
at sun.java2d.pipe.DrawImage.copyImage
at sun.java2d.pipe.ValidatePipe.copyImage
at sun.java2d.SunGraphics2D.drawImage
at sun.java2d.SunGraphics2D.drawImage
at <our code>
来自 GDB 的该线程的堆栈跟踪如下所示:
in poll()
in XAddConnectionWatch()
in _XRead()
in _XReply()
in XSync()
in X11SD_GetRasInfo()
in Java_sun_java2d_loops_Blit_Blit
in ??
此外,我们的应用程序通常有几个线程在后台渲染到 VolatileImages。处于这种状态时,这些线程始终处于 RUNNABLE 状态,但会陷入以下调用中:
at sun.java2d.loops.FillRect.FillRect (Native Method)
at sun.java2d.pipe.LoopPipe.fillRect
at sun.java2d.SunGraphics2D.fillRect
at sun.java2d.SunGraphics2D.clearRect
at <our code: rendering to a VolatileImage>
并且这些线程的 GDB 堆栈跟踪是:
in pthread_cond_wait@@GLIBC_2.3.2
in Monitor::wait
in GC_locker::jni_lock_slow
in jni_GetPrimitiveArrayCritical
in BufImg_GetRasInfo
in Java_sun_java2d_loops_FillRect_FillRect
in ??
以前有人见过类似的情况吗?我们完全被难住了,我什至不知道下一步该做什么来尝试解决问题。
编辑:问题仍然存在。在 JStack 和 gdb 堆栈转储上,AWT 事件队列基本上总是看起来相同;我们已经看到这种情况发生,没有其他线程同时卡住,正如我最初描述的那样。
谢谢!
EDIT: additional info at the end
I've got a (large) Java Swing application that's demonstrating some very strange behavior. If the computer running it is left idle (no mouse or keyboard input) for a sufficiently long time (varies between an hour or so and a couple of days), the Swing display sometimes stops updating totally (we've got, among other things, a clock shown on-screen that stops updating) until the user moves the mouse. Once the mouse has been moved, our application seems to function normally. (Creating and removing a window from another application also causes the display to start updating again; keyboard input doesn't appear to be sufficient.)
We're running Sun's JDK 1.6.0_07 on Linux kernel 2.6.25.14 (I think it's a modified RHEL 4 distro, but I'm not sure offhand) running xorg-x11-server 1.1.1-48.13.e15.
When in this state, the AWT Event Queue is always "Runnable", and in one of a few java2d methods - the most recent example I have is:
at sun.java2d.loops.Blit.Blit (native method)
at sun.java2d.pipe.DrawImage.blitSurfaceData
at sun.java2d.pipe.DrawImage.renderImageCopy
at sun.java2d.pipe.DrawImage.copyImage
at sun.java2d.pipe.DrawImage.copyImage
at sun.java2d.pipe.ValidatePipe.copyImage
at sun.java2d.SunGraphics2D.drawImage
at sun.java2d.SunGraphics2D.drawImage
at <our code>
And the stack trace from GDB for that thread looks like:
in poll()
in XAddConnectionWatch()
in _XRead()
in _XReply()
in XSync()
in X11SD_GetRasInfo()
in Java_sun_java2d_loops_Blit_Blit
in ??
In addition, our application usually has a couple of threads that render to VolatileImages in the background. When in this state, these threads are always RUNNABLE but stuck in calls like:
at sun.java2d.loops.FillRect.FillRect (Native Method)
at sun.java2d.pipe.LoopPipe.fillRect
at sun.java2d.SunGraphics2D.fillRect
at sun.java2d.SunGraphics2D.clearRect
at <our code: rendering to a VolatileImage>
and the GDB stack trace for these threads is:
in pthread_cond_wait@@GLIBC_2.3.2
in Monitor::wait
in GC_locker::jni_lock_slow
in jni_GetPrimitiveArrayCritical
in BufImg_GetRasInfo
in Java_sun_java2d_loops_FillRect_FillRect
in ??
Has anyone seen anything like this before? We're completely stumped, and I'm not even sure what to do next to try and pin down the problem.
EDIT: the problem continues. The AWT Event Queue basically always looks the same, on both the JStack and gdb stack dumps; we've seen this happen with no other threads getting simultaneously stuck as I described initially.
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
抱歉,我不使用任何 Java2D 的东西,所以我不能确定——但首先想到的是你的一个后台线程正在渲染到实时上下文。
如果是这种情况,那么在非常非常罕见的情况下,它可能会与 AWT 线程(唯一允许实际渲染的线程)发生冲突,如果发生这种情况,您可以轻松获得像您所看到的结果 - 事实上,这就是正是我所期望的。
我可能是错的,但即使你认为我是错的,为什么不尝试让你的后台线程实际上在 WorkerThread 上执行任务——尝试一下也没有什么坏处,即使它在测试过程中会稍微影响你的性能。
Sorry, I don't work with any of the Java2D stuff so I can't be sure--but the first thing that comes to mind is one of your background threads is rendering to a live context.
If this is the case, then in very very rare cases, it can collide with the AWT thread (the ONLY thread allowed to actually render), and if this happens, you could easily get results like you are seeing--in fact, that's exactly what I'd expect.
I could be wrong, but even if you think I am, why not experiment with having your background threads actually do their tasks on a WorkerThread--it can't hurt to try it even if it screws up your performance a little during the test.