本文介绍了Eclipse挂起永远,线程转储说主线程正在睡觉的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在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; 
while(System.currentTimeMillis()< timeout){
eventPtr = OS.gdk_event_get();
if(eventPtr!= 0){
break;
} else {
try {Thread.sleep(50);} catch(Exception ex){}
}
}
/ pre>

如果是,请在,您可以轻松地使用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, and currentTimeMillis isn't guaranteed to be monotonic (unlike System.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挂起永远,线程转储说主线程正在睡觉的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-20 17:03