问题描述
我在Solaris 11 X86中运行Eclipse 3.7.2。它随机地挂起(每几个小时或几分钟)。当它挂起时,我做一个线程转储,它表明主要
线程处于等待状态。 Eclipse不会从睡眠状态唤醒并变得无响应,我必须重新启动Eclipse才能再次使用它。 主线程正在睡眠,因为:
org.eclipse.swt.widgets.Control.dragDetect
有没有任何已知的修复这个问题?
编辑:
操作系统
SunOS solaris 5.11 11.0 i86pc i386 i86pc Solaris
完整堆栈跟踪:
mainprio = 3 tid = 0x080e8400 nid = 0x1等待条件[0x08045000]
java.lang.Thread.State:TIMED_WAITING(sleeping)
在java.lang.Thread.sleep(Native Method)
在org.eclipse.swt。 widgets.Control.dragDetect(Control.java:2204)
在org.eclipse.swt.widgets.Tree.dragDetect(Tree.java:1125)
在org.eclipse.swt.widgets.Control。 gtk_button_press_event(Control.java:2791)
在org.eclipse.swt.widgets.Control.gtk_button_press_event(Control.java:2759)
在org.eclipse.swt.widgets.Composite.gtk_button_press_event(Composite.java:681)
在org.eclipse.swt.widgets.Tree.gtk_button_press_event(Tree.java:1871)
在org.eclipse.swt.widgets.Widget.windowProc(Widget.java:1731)
在org.eclipse.swt.widgets.Control.windowProc(Control.java:5016)
在org.eclipse .swt.widgets.Tree.windowProc(Tree.java:3530)
在org.eclipse.swt.widgets.Display.windowProc(Display.java:4408)
在org.eclipse.swt.internal .gtk.OS._gtk_main_do_event(Native Method)
在org.eclipse.swt.internal.gtk.OS.gtk_main_do_event(OS.java:8422)
在org.eclipse.swt.widgets.Display。 eventProc(Display.java:1245)
在org.eclipse.swt.internal.gtk.OS._g_main_context_iteration(本机方法)
在org.eclipse.swt.internal.gtk.OS.g_main_context_iteration(OS .java:2276)
在org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3207)
在org.eclipse.ui.internal.Workbench.runEventLoop(Workbench .java:2701)
在org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2665)
在org.eclipse.ui.internal.Workbench.access $ 4(Workbench.java: 2499)
在org.eclipse.ui.internal.Workbench $ 7.run(Workbench.java:679)
在org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332 )
在org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:668)
在org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
在$ org.eclipse.equinox.internal.app.EclipseAppHandle.run b在org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)中的org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)上的
)
在org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:344)
在org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke( NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
在java.lang.reflect.Method.invoke(Method.java:601)
在org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:622)
在org.eclipse.equinox.launcher.Main.basicRun(Main.java:577)
在org.eclipse .equinox.launcher.Main.run(Main.java:1410)
锁定的拥有同步器:
- 无
VM线程prio = 3 tid = 0x08209c00 nid = 0x2 runnable
VM定期任务线程prio = 3 tid = 0x0825d000 nid = 0x8等待条件
JNI全局引用:713
您的系统时钟是否可以跳过?
Eclipse的事件循环使用 System.currentTimeMillis()
来跟踪时间,而 currentTimeMillis
不能保证是单调的(不像 System.nanoTime()
一直是。)
long timeout = System.currentTimeMillis()+ 500;
/ pre>
while(System.currentTimeMillis()< timeout){
eventPtr = OS.gdk_event_get();
if(eventPtr!= 0){
break;
} else {
try {Thread.sleep(50);} catch(Exception ex){}
}
}
如果是,请在,您可以轻松地使用JBoss Byteman创建一个规则集,该规则集在一定数量的睡眠后从睡眠循环中缓存。 p>
Foo.java:
public class Foo {
public void test1(){
long timeout = System.currentTimeMillis()+ 500;
int i = 0;
while(System.currentTimeMillis()< timeout){
System.out.println(i ++);
try {Thread.sleep(50);} catch(Exception ex){}
}
}
public static void main ... args)throws Exception {
new Foo()。test1();
}
}
sleeper.btm:
规则计数器
CLASS Foo
方法test1
AT ENTRY
如果TRUE
DO createCountDown($ 0,5)
ENDRULE
规则休眠
CLASS Foo
方法test1
AT INVOKE Thread.sleep()
如果countDown($ 0)
DO RETURN
ENDRULE
使用Byteman脚本运行:
$〜/下载/ byteman-download-2.1.0 / bin / bmjava.sh -l ./sleeper.btm Foo
0
1
2
3
4
5
正常运行:
$ java Foo
0
1
2
3
4
5
6
7
8
9
I am running Eclipse 3.7.2 in Solaris 11 X86. It hangs randomly (every few hours or every few minutes). When it hangs, I do a thread dump and it suggests that
Main
thread is in timed wait state. Eclipse never wakes up from the sleep state and becomes unresponsive, I have to restart Eclipse to use it again.Main thread is sleeping because of:
org.eclipse.swt.widgets.Control.dragDetect
Is there any known fix to this issue?
Edit:
OS
SunOS solaris 5.11 11.0 i86pc i386 i86pc Solaris
Full stack trace:
"main" prio=3 tid=0x080e8400 nid=0x1 waiting on condition [0x08045000] java.lang.Thread.State: TIMED_WAITING (sleeping) at java.lang.Thread.sleep(Native Method) at org.eclipse.swt.widgets.Control.dragDetect(Control.java:2204) at org.eclipse.swt.widgets.Tree.dragDetect(Tree.java:1125) at org.eclipse.swt.widgets.Control.gtk_button_press_event(Control.java:2791) at org.eclipse.swt.widgets.Control.gtk_button_press_event(Control.java:2759) at org.eclipse.swt.widgets.Composite.gtk_button_press_event(Composite.java:681) at org.eclipse.swt.widgets.Tree.gtk_button_press_event(Tree.java:1871) at org.eclipse.swt.widgets.Widget.windowProc(Widget.java:1731) at org.eclipse.swt.widgets.Control.windowProc(Control.java:5016) at org.eclipse.swt.widgets.Tree.windowProc(Tree.java:3530) at org.eclipse.swt.widgets.Display.windowProc(Display.java:4408) at org.eclipse.swt.internal.gtk.OS._gtk_main_do_event(Native Method) at org.eclipse.swt.internal.gtk.OS.gtk_main_do_event(OS.java:8422) at org.eclipse.swt.widgets.Display.eventProc(Display.java:1245) at org.eclipse.swt.internal.gtk.OS._g_main_context_iteration(Native Method) at org.eclipse.swt.internal.gtk.OS.g_main_context_iteration(OS.java:2276) at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3207) at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2701) at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2665) at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2499) at org.eclipse.ui.internal.Workbench$7.run(Workbench.java:679) at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332) at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:668) at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149) at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:123) at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110) at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79) at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:344) at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:601) at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:622) at org.eclipse.equinox.launcher.Main.basicRun(Main.java:577) at org.eclipse.equinox.launcher.Main.run(Main.java:1410) Locked ownable synchronizers: - None "VM Thread" prio=3 tid=0x08209c00 nid=0x2 runnable "VM Periodic Task Thread" prio=3 tid=0x0825d000 nid=0x8 waiting on condition JNI global references: 713
解决方案Is it possible that your system clock is jumping around?
Eclipse's event loop uses
System.currentTimeMillis()
to keep track of time, andcurrentTimeMillis
isn't guaranteed to be monotonic (unlikeSystem.nanoTime()
would have been.)long timeout = System.currentTimeMillis() + 500; while (System.currentTimeMillis() < timeout) { eventPtr = OS.gdk_event_get (); if (eventPtr != 0) { break; } else { try {Thread.sleep(50);} catch (Exception ex) {} } }
If so, as a workaround you requested at " Is there a way to interrupt a sleeping thread in a running JVM, without having access to the application's code? ", you can easily use JBoss Byteman to create a rule set, which bails from the sleep loop after a set number of sleeps.
Foo.java:
public class Foo { public void test1() { long timeout = System.currentTimeMillis() + 500; int i = 0; while (System.currentTimeMillis() < timeout) { System.out.println(i++); try {Thread.sleep(50);} catch (Exception ex) {} } } public static void main(final String ... args) throws Exception { new Foo().test1(); } }
sleeper.btm:
RULE counter CLASS Foo METHOD test1 AT ENTRY IF TRUE DO createCountDown($0, 5) ENDRULE RULE sleeper CLASS Foo METHOD test1 AT INVOKE Thread.sleep() IF countDown($0) DO RETURN ENDRULE
Run with Byteman script:
$ ~/Downloads/byteman-download-2.1.0/bin/bmjava.sh -l ./sleeper.btm Foo 0 1 2 3 4 5
Run normally:
$ java Foo 0 1 2 3 4 5 6 7 8 9
这篇关于Eclipse挂起永远,线程转储说主线程正在睡觉的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!