【问题标题】:Java Swing display stops updating until X event generatedJava Swing 显示停止更新,直到生成 X 事件
【发布时间】:2011-01-13 13:16:31
【问题描述】:

编辑:最后的附加信息

我有一个(大型)Java Swing 应用程序,它展示了一些非常奇怪的行为。如果运行它的计算机闲置(没有鼠标或键盘输入)足够长的时间(在一个小时左右到几天之间变化),Swing 显示器有时会完全停止更新(我们有,除其他外) ,一个显示在屏幕上的时钟,停止更新),直到用户移动鼠标。移动鼠标后,我们的应用程序似乎可以正常运行。 (从另一个应用程序创建和删除窗口也会导致显示再次开始更新;键盘输入似乎不够。)

我们在运行 xorg-x11-server 1.1.1-48.13.e15 的 Linux 内核 2.6.25.14 上运行 Sun 的 JDK 1.6.0_07(我认为它是经过修改的 RHEL 4 发行版,但我不确定)。

当处于这种状态时,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 事件队列基本上总是相同的;正如我最初描述的那样,我们已经看到没有其他线程同时卡住。

谢谢!

【问题讨论】:

  • Sun BugParade 是一个值得一看的好地方(最近显然已更名为 Oracleish)bugs.sun.com - 但我会首先尝试简单地将 JVM 升级到最新的 Sun 官方版本.
  • 我没有设法在 Sun 错误数据库中找到任何可能的东西 - 这是我检查的第一件事。遗憾的是,由于我无法控制的原因,我们被锁定在这个特定的 JVM 版本中。不过,感谢您的建议。
  • Sbodd,听起来您的问题和我的问题 (stackoverflow.com/questions/2233529/…) 可能是由相同的根本问题引起的。不幸的是,我还没有找到解决方案。

标签: java linux swing x11


【解决方案1】:

抱歉,我不使用任何 Java2D 东西,所以我不能确定 - 但首先想到的是您的一个后台线程正在渲染到实时上下文。

如果是这种情况,那么在极少数情况下,它可能会与 AWT 线程(唯一允许实际渲染的线程)发生冲突,如果发生这种情况,您很容易得到您所看到的结果——在事实上,这正是我所期望的。

我可能是错的,但即使你认为我错了,为什么不尝试让你的后台线程实际在 WorkerThread 上执行它们的任务——即使它会稍微搞砸你的性能,尝试一下也无妨在测试期间。

【讨论】:

  • 我认为这不会发生,除非我误解了“实时上下文”的构成。来自 BufferedImage.getGraphics() 或 VolatileImage.getGraphics() 的图形是否曾经是实时上下文?
  • 我们在 Swing 应用程序中发现了一些问题,如果您不小心在后台线程中从 AWT 事件队列中执行了一些 GUI 操作,您可以轻松地锁定 GUI。一开始你可以侥幸逃脱,直到后来它随机锁定。这就是听起来的样子。至少,您应该检查一下这条途径。 java.sun.com/products/jfc/tsc/articles/threads/threads1.html
猜你喜欢
  • 2018-08-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-19
  • 2012-03-21
  • 2011-11-29
  • 2019-11-27
相关资源
最近更新 更多