`

org.eclipse.swt.SWTError: No more handles 续

 
阅读更多
[url]SWT中org.eclipse.swt.SWTError: No more handles[/url] 一文中有介绍,但最近又遇到这个问题。

其实,在那篇文章中提到的用Map 模拟注册表 缓存的方法是很凑效的,之所以又出现这个异常是因为一时疏漏 在一个方法中new Image后没有及时dispose该image(由于该image在Graphics中调用属于临时image 没必要放到map中,正确的方法是用完后dispose),而该方法又被频繁调用,这就又导致了该异常。

虽然最后的解决方案很简单,就添加一行image.dispose就ok了,不过由于项目比较大,想快速定位到错误的位置并不容易。

所以,如何跟踪软件(这里针对Eclipse RCP程序进行说明)的handler消耗呢?

其实打开Windows的任务管理器,可以在“性能”子页下的 句柄总数找到句柄的描述信息,但是如果我们想要知道RCP程序中具体的handler消耗,这个显然是不够的。

用Sleak工具可以快速定位句柄的消耗情况,来快速查出被过度消耗的handler出现在何处:

Sleak工具主要就是 org.eclipse.swt.sleak.jar 这个jar包,可以在http://www.eclipse.org/swt/tools.php 下载到。

http://www.eclipse.org/articles/swt-design-2/sleak.htm 官网上sleak的介绍

该包就有两个有效类Sleak.java和SleakView.java

import org.eclipse.swt.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.widgets.*;
import java.io.*;

/**
 * Instructions on how to use the Sleak tool.
 * 
 * A) If you have access to the place where the display is created (most standalone applications):
 * 
 * Modify the creation of the Display as follows:
 * 
 * DeviceData data = new DeviceData();
 * data.tracking = true;
 * Display display = new Display(data);
 * Sleak sleak = new Sleak();
 * sleak.open();
 * Shell shell = new Shell(display);
 * 
 * B) If you do not have access to the place where the display is created (Eclipse):
 * 
 * 1) This tool will be referenced from the Device class so it needs to be copied into the same project.  
 *     Copy the package org.eclipse.swt.internal.tools to a source folder in the org.eclipse.swt project.
 * 
 * 2) This tool relies on debug information collected by the Device class.  Modify the Device class to 
 *     turn DEBUG on:
 * 
 *    public static boolean DEBUG = true;
 * 
 * 3)  The Sleak tool must be launched from the constructor of the Device class.
 *      Add the following lines to the end of the Device constructor:
 * 
 *   if (this.getClass().getName().equals("org.eclipse.swt.widgets.Display")) {
 *    org.eclipse.swt.internal.tools.Sleak sleak = new org.eclipse.swt.internal.tools.Sleak();
 *    sleak.open();
 *   }
 * 
 * 4) Create a new swt.jar for the platform you wish to test.  This is done by running the build.xml script 
 *     in the appropriate windowing system fragment.  Select the ws/$ws/swt.jar target.
 * 
 * 5) Copy the new swt.jar to the appropriate location.  When using Sleak with Eclipse, this is
 *     eclipse/org.eclipse.swt.<ws>_<version>/ws/<ws>
 * 
 * 6) Launch your application and the Sleak GUI will be displayed.  Click on the Snap button to
 *     capture the current resource state.  Click on the Diff button to compare the current state to 
 *     the previous snapshot state.
 * 
 */
public class Sleak {
 Display display;
 Composite parent;
 List list;
 Canvas canvas;
 Button start, stop, check;
 Text text;
 Label label;
 
 Object [] oldObjects = new Object [0];
 Error [] oldErrors = new Error [0];
 Object [] objects = new Object [0];
 Error [] errors = new Error [0];


public void open () {
 Display display = Display.getCurrent ();
 Shell shell = new Shell (display);
 shell.setText ("S-Leak");
 open (shell);
}
public void open (Composite parent2) {
 Composite composite = new Composite(parent2, SWT.NONE);
 parent = composite;
 parent.addListener(SWT.Resize, new Listener() {
  public void handleEvent (Event e) {
   layout ();
  }
 });
 this.display = Display.getCurrent ();
 list = new List (parent, SWT.BORDER | SWT.V_SCROLL);
 list.addListener (SWT.Selection, new Listener () {
  public void handleEvent (Event event) {
   refreshObject ();
  }
 });
 text = new Text (parent, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL);
 canvas = new Canvas (parent, SWT.BORDER);
 canvas.addListener (SWT.Paint, new Listener () {
  public void handleEvent (Event event) {
   paintCanvas (event);
  }
 });
 check = new Button (parent, SWT.CHECK);
 check.setText ("Stack");
 check.addListener (SWT.Selection, new Listener () {
  public void handleEvent (Event e) {
   toggleStackTrace ();
  }
 });
 start = new Button (parent, SWT.PUSH);
 start.setText ("Snap");
 start.addListener (SWT.Selection, new Listener () {
  public void handleEvent (Event event) {
   refreshAll ();
  }
 });
 stop = new Button (parent, SWT.PUSH);
 stop.setText ("Diff");
 stop.addListener (SWT.Selection, new Listener () {
  public void handleEvent (Event event) {
   refreshDifference ();
  }
 });
 label = new Label (parent, SWT.BORDER);
 label.setText ("0 object(s)");
 parent.addListener (SWT.Resize, new Listener () {
  public void handleEvent (Event e) {
   layout ();
  }
 });
 check.setSelection (false);
 text.setVisible (false);
 Point size = parent.getSize ();
 parent.setSize (size.x / 2, size.y / 2);
 parent.setVisible (true);
}

void refreshLabel () {
 int colors = 0, cursors = 0, fonts = 0, gcs = 0, images = 0;
 int paths = 0, patterns = 0, regions = 0, textLayouts = 0, transforms= 0;
 for (int i=0; i<objects.length; i++) {
  Object object = objects [i];
  if (object instanceof Color) colors++;
  if (object instanceof Cursor) cursors++;
  if (object instanceof Font) fonts++;
  if (object instanceof GC) gcs++;
  if (object instanceof Image) images++;
  if (object instanceof Path) paths++;
  if (object instanceof Pattern) patterns++;
  if (object instanceof Region) regions++;
  if (object instanceof TextLayout) textLayouts++;
  if (object instanceof Transform) transforms++;
 }
 String string = "";
 if (colors != 0) string += colors + " Color(s)\n";
 if (cursors != 0) string += cursors + " Cursor(s)\n";
 if (fonts != 0) string += fonts + " Font(s)\n";
 if (gcs != 0) string += gcs + " GC(s)\n";
 if (images != 0) string += images + " Image(s)\n";
 if (paths != 0) string += paths + " Paths(s)\n";
 if (patterns != 0) string += patterns + " Pattern(s)\n";
 if (regions != 0) string += regions + " Region(s)\n";
 if (textLayouts != 0) string += textLayouts + " TextLayout(s)\n";
 if (transforms != 0) string += transforms + " Transform(s)\n";
 if (string.length () != 0) {
  string = string.substring (0, string.length () - 1);
 }
 label.setText (string);
}

void refreshDifference () {
 DeviceData info = display.getDeviceData ();
 if (!info.tracking) {
  MessageBox dialog = new MessageBox (parent.getShell(), SWT.ICON_WARNING | SWT.OK);
  dialog.setText (parent.getShell().getText ());
  dialog.setMessage ("Warning: Device is not tracking resource allocation");
  dialog.open ();
 }
 Object [] newObjects = info.objects;
 Error [] newErrors = info.errors;
 Object [] diffObjects = new Object [newObjects.length];
 Error [] diffErrors = new Error [newErrors.length];
 int count = 0;
 for (int i=0; i<newObjects.length; i++) {
  int index = 0;
  while (index < oldObjects.length) {
   if (newObjects [i] == oldObjects [index]) break;
   index++;
  }
  if (index == oldObjects.length) {
   diffObjects [count] = newObjects [i];
   diffErrors [count] = newErrors [i];
   count++;
  }
 }
 objects = new Object [count];
 errors = new Error [count];
 System.arraycopy (diffObjects, 0, objects, 0, count);
 System.arraycopy (diffErrors, 0, errors, 0, count);
 list.removeAll ();
 text.setText ("");
 canvas.redraw ();
 for (int i=0; i<objects.length; i++) {
  list.add (objects [i].toString());
 }
 refreshLabel ();
 layout ();
}

void toggleStackTrace () {
 refreshObject ();
 layout ();
}

void paintCanvas (Event event) {
 canvas.setCursor (null);
 int index = list.getSelectionIndex ();
 if (index == -1) return;
 GC gc = event.gc;
 Object object = objects [index];
 if (object instanceof Color) {
  if (((Color)object).isDisposed ()) return;
  gc.setBackground ((Color) object);
  gc.fillRectangle (canvas.getClientArea());
  return;
 }
 if (object instanceof Cursor) {
  if (((Cursor)object).isDisposed ()) return;
  canvas.setCursor ((Cursor) object);
  return;
 }
 if (object instanceof Font) {
  if (((Font)object).isDisposed ()) return;
  gc.setFont ((Font) object);
  FontData [] array = gc.getFont ().getFontData ();
  String string = "";
  String lf = text.getLineDelimiter ();
  for (int i=0; i<array.length; i++) {
   FontData data = array [i];
   String style = "NORMAL";
   int bits = data.getStyle ();
   if (bits != 0) {
    if ((bits & SWT.BOLD) != 0) style = "BOLD ";
    if ((bits & SWT.ITALIC) != 0) style += "ITALIC";
   }
   string += data.getName () + " " + data.getHeight () + " " + style + lf;
  }
  gc.drawString (string, 0, 0);
  return;
 }
 //NOTHING TO DRAW FOR GC
// if (object instanceof GC) {
//  return;
// }
 if (object instanceof Image) {
  if (((Image)object).isDisposed ()) return;
  gc.drawImage ((Image) object, 0, 0);
  return;
 }
 if (object instanceof Path) {
  if (((Path)object).isDisposed ()) return;
  gc.drawPath ((Path) object);
  return;
 }
 if (object instanceof Pattern) {
  if (((Pattern)object).isDisposed ()) return;
  gc.setBackgroundPattern ((Pattern)object);
  gc.fillRectangle (canvas.getClientArea ());
  gc.setBackgroundPattern (null);
  return;
 }
 if (object instanceof Region) {
  if (((Region)object).isDisposed ()) return;
  String string = ((Region)object).getBounds().toString();
  gc.drawString (string, 0, 0);
  return;
 }
 if (object instanceof TextLayout) {
  if (((TextLayout)object).isDisposed ()) return;
  ((TextLayout)object).draw (gc, 0, 0);
  return;
 }
 if (object instanceof Transform) {
  if (((Transform)object).isDisposed ()) return;
  String string = ((Transform)object).toString();
  gc.drawString (string, 0, 0);
  return;
 }
}

void refreshObject () {
 int index = list.getSelectionIndex ();
 if (index == -1) return;
 if (check.getSelection ()) {
  ByteArrayOutputStream stream = new ByteArrayOutputStream ();
  PrintStream s = new PrintStream (stream);
  errors [index].printStackTrace (s);
  text.setText (stream.toString ());
  text.setVisible (true);
  canvas.setVisible (false);
 } else {
  canvas.setVisible (true);
  text.setVisible (false);
  canvas.redraw ();
 }
}

void refreshAll () {
 oldObjects = new Object [0];
 oldErrors = new Error [0];
 refreshDifference ();
 oldObjects = objects;
 oldErrors = errors;
}

void layout () {
 Rectangle rect = parent.getClientArea ();
 int width = 0;
 String [] items = list.getItems ();
 GC gc = new GC (list);
 for (int i=0; i<objects.length; i++) {
  width = Math.max (width, gc.stringExtent (items [i]).x);
 }
 gc.dispose ();
 Point size1 = start.computeSize (SWT.DEFAULT, SWT.DEFAULT);
 Point size2 = stop.computeSize (SWT.DEFAULT, SWT.DEFAULT);
 Point size3 = check.computeSize (SWT.DEFAULT, SWT.DEFAULT);
 Point size4 = label.computeSize (SWT.DEFAULT, SWT.DEFAULT);
 width = Math.max (size1.x, Math.max (size2.x, Math.max (size3.x, width)));
 width = Math.max (64, Math.max (size4.x, list.computeSize (width, SWT.DEFAULT).x));
 start.setBounds (0, 0, width, size1.y);
 stop.setBounds (0, size1.y, width, size2.y);
 check.setBounds (0, size1.y + size2.y, width, size3.y);
 label.setBounds (0, rect.height - size4.y, width, size4.y);
 int height = size1.y + size2.y + size3.y;
 list.setBounds (0, height, width, rect.height - height - size4.y);
 text.setBounds (width, 0, rect.width - width, rect.height);
 canvas.setBounds (width, 0, rect.width - width, rect.height);
}
}
==============
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.part.*;

/**
 * This sample class demonstrates how to plug-in a new
 * workbench view. The view shows data obtained from the
 * model. The sample creates a dummy model on the fly,
 * but a real implementation would connect to the model
 * available either in this or another plug-in (e.g. the workspace).
 * The view is connected to the model using a content provider.
 * <p>
 * The view uses a label provider to define how model
 * objects should be presented in the view. Each
 * view can present the same model objects using
 * different labels and icons, if needed. Alternatively,
 * a single label provider can be shared between views
 * in order to ensure that objects of the same type are
 * presented in the same way everywhere.
 * <p>
 */

public class SleakView extends ViewPart {

 Composite parent = null;
 Sleak sleak = null;

 /**
  * The constructor.
  */
 public SleakView() {
 }

 /**
  * This is a callback that will allow us
  * to create the viewer and initialize it.
  */
 public void createPartControl(Composite parent) {
  this.parent = parent;
  sleak = new Sleak ();
  sleak.open(parent);
  sleak.layout();
 }

 /**
  * Passing the focus request to the viewer's control.
  */
 public void setFocus() {
 }

}

================

可以把以上两个类copy到自己的工程下面,扩展一个view 结点,指定实现类为SleakView 就可以了。
<extension
         point="org.eclipse.ui.views">
      <category
            id="org.xxx.xxx.rcp.category"
            name="Sleak 工具">
      </category>
      <view
            category="org.xxx.xxx.rcp.category"
            class="org.xxx.xxx.rcp.sleak.SleakView"
            id="org.eclipse.swt.sleak.views.SleakView"
            name="Sleak00kaelS"
            restorable="true">
      </view>
   </extension>

这样在你运行你的项目的时候就可看到Sleak View了,能够很容易跟踪handler的消耗。
分享到:
评论

相关推荐

    GUI_handles.zip_GUI_handles_GUI_handles.zip _MATLAB GUI源代码_Matla

    "GUI_handles.zip"是一个包含MATLAB GUI源代码的压缩包,特别针对"handles"这一主题,旨在帮助用户深入理解并熟练掌握MATLAB GUI的编写。 在MATLAB GUI中,"handles"是一个关键概念,它是一种数据结构,存储了GUI...

    flex-object-handles.zip_flex

    在Flex开发中,"flex-object-handles.zip_flex"这个压缩包可能包含了关于如何操作和交互Flex中的对象,特别是涉及到对象的移动、编译、放大和缩小功能的代码示例或教程。Flex是一种基于ActionScript和MXML的开源框架...

    xulrunner-1.9.2.28pre.en-US.linux-x86_64.tar.rar

    org.eclipse.swt.SWTError: No more handles [MOZILLA_FIVE_HOME=''] (java.lang.UnsatisfiedLinkError: Could not load SWT library. Reasons: no swt-mozilla-gtk-4335 in java.library.path no swt-mozilla-gtk ...

    关于Unhandled event loop exception No more handles的两种解决方案

    在使用Eclipse开发工具的过程中,有时会遇到一个较为棘刺的问题——出现“Unhandled event loop exception No more handles”的错误提示。这一错误不仅令人困惑,而且严重影响了Eclipse的正常使用。本文旨在通过分析...

    xulrunner-1.9.2.28pre.en-US.linux-x86_64.tar

    解决org.eclipse.swt.SWTError: No more handles [MOZILLA_FIVE_HOME=''] (java.lang.UnsatisfiedLinkError: Could not load SWT library. Reasons: no swt-mozilla-gtk-4335 in java.library.path

    java的常见问题及解决方法参照.pdf

    如果在Java应用中使用XULRunner嵌入浏览器,但遇到"Exception in thread "main" org.eclipse.swt.SWTError: No more handles [Could not detect registered XULRunner to use]",你需要确保XULRunner已经正确注册。...

    java的常见问题及解决方法定义.pdf

    在Java应用中嵌入浏览器时,如果遇到“Exception in thread "main" org.eclipse.swt.SWTError: No more handles [Could not detect registered XULRunner to use]”的异常,意味着XULRunner未注册。在Windows环境下...

    gef 转折线的相关方法实现和 GEF的API chm 格式

    - `org.eclipse.gef.handles`包下的类:用于创建图形元素的手柄,用户可以通过手柄进行交互操作,如拖动转折点。 GEF的API文档通常以CHM(Compiled HTML Help)格式提供,这是一种Windows平台下的帮助文档格式,...

    雾霾分析的MATLAB GUI仿真程序

    gxq=handles.gxq;hgxq=handles.hgxq; jkq=handles.jkq;hjkq=handles.hjkq; xz=handles.xz;hxz=handles.hxz; xq=handles.xq;hxq=handles.hxq; gyt=handles.gyt;hgyt=handles.hgyt; qj=handles.qj;hqj=handles.hqj; lt...

    Matplotlib添加图例时解决报错:No handles with labels found to put in legend.

    然而,有时可能会遇到"Matplotlib添加图例时报错:No handles with labels found to put in legend."这样的问题。这个错误是因为在尝试添加图例时,Matplotlib无法找到具有指定标签的图形对象,即没有给任何绘图函数...

    Runtime Transform Handles,可再unity运行时拖拽旋转物体,可用于制作场景编辑器等功能

    Runtime Transform Handles,可再unity运行时拖拽旋转物体,可用于制作场景编辑器等功能

    objecthandles_demo.rar

    标题“objecthandles_demo.rar”指的是一个包含有关ObjectHandles功能的示例或教程的压缩文件。ObjectHandles在IT行业中通常指的是在图形用户界面(GUI)设计工具或编程环境中,用于直观地操纵和调整对象属性的交互...

    ocl资源文件dll

    当你遇到“Navicat is not able to create OCI handles”这样的错误时,通常是因为系统缺少或者版本不匹配的"ocl.dll"导致的。Navicat是一款流行的数据管理和开发工具,它在尝试建立与Oracle数据库的连接时,需要...

    OD插件-ollysseh

    This plugin does an in-memory scanning of process loaded modules checking if they were compiled with /SafeSEH, if so it can list the registered ... Error : There was an error reading module structure :-

    论文研究-Mozilla缺陷报告仓库特征分析 .pdf

    从给定的文件信息中,我们可以提取以下知识点: 1. 开源软件缺陷报告管理的重要性: 开源软件项目的维护工作关键在于保持产品的实用性和耐用性,其中,缺陷报告仓库管理是一个重要的方面。在大型开源项目中,比如...

    Runtime Transform Handles. 不是新版本,在unity2022.1.16中测试没有问题,

    在Unity引擎中,Runtime Transform Handles是一项实用的功能,它允许开发者在运行时动态地操纵游戏对象的变换属性,如位置、旋转和缩放。这个特性在2D和3D场景编辑、交互式应用或者游戏设计中非常有用,因为它提供了...

    leaked-handles:检测节点中泄漏的任何句柄

    no of handles 1 timer handle (`setTimeout(any, 1000)`) timer handle leaked at one of: at Test.t (/home/raynos/uber/leaked-handles/test/leak-timer.js:10:17) timer listener function any() {} no of ...

    RAY.zip_ GUIDATA and GCBO_ray-tracing wireless_startup

    handles.figure1, handles.slider2. This | structure is created at GUI startup using GUIHANDLES and stored in | the figure s application data using GUIDATA. A copy of the structure | is passed to ...

    Runtime Transform Handles

    在Unity引擎中,"Runtime Transform Handles"是一种高级的交互技术,允许用户在运行时通过直观的手柄来操纵场景中的对象,实现对物体的平移、缩放和旋转等操作。这种技术广泛应用于游戏开发、虚拟现实(VR)应用以及...

Global site tag (gtag.js) - Google Analytics