用Sleak工具来检测句柄泄漏 SWTError: No more handles 终极解决!

以下描述绝对适用于Eclipse RCP程序,稍作改动应该可以适用于SWT程序。

背景以及问题简单描述:

SWT中的每一个Widget,Font,Image,Color等等,引用的资源都是OS Resource,而不仅仅是Java世界所拥有的。

我相信我们的RCP程序,SWT程序肯定会用到这些东西。这些东西跟Java Objects不同的地方是,Java Objects在不用

的时候(置为null)会被GC回收,而这些OS Resource不会被GC回收。

32Bit的OS 为每一个Process分配的handles数目是10000,Windows OS 可以查看注册表:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\ CurrentVersion\Windows\ USERProcessHandleQuota and GDIProcessHandleQuota

在Google上搜索 SWT No more handles 很容易搜到SWT 官方提供的一些资料,我大致说下我看后对主要问题的理解:

Rule 1: If you created it, you dispose it.

Rule 2: Disposing the parent disposes the children.

我们很可能在不经意间已经直接或间接调用了一些资源的create方法,而我们没有注意他们的 javadoc:如果你调用这个方法,你有责任调用dispose方法来释放资源。

这样的话,就出现了资源(句柄)泄漏。如何检测我们的程序是否有资源泄漏呢?用Sleak。

下面的可看可不看,是我在探索问题过程中发给组内同事的mail内容

体会:

Rule1: 如果我们显示的调用了类如: Image image = new Image(…); 的代码的话,我们需要手动调用image.dispose(); 否则每次new Image()都是一个资源泄漏

关于Image对象,比如我们有一个方法:

public static void createImages(ImageData imageData, int i ) {

      Image image = new Image(display, imageData);

      System.out.println("image " + i);

      image = null;

      //image.dispose();

    }

循环10000次,这个方法在执行第3313次的时候,出现了Exception in thread "main" org.eclipse.swt.SWTError: No more handles

如果启用 image.dispose(), 则没有问题。

Text 和 Label,这样的资源,通过在一个Editor中加入下面的代码:

   for (int i = 0; i< 10000; i++) {

        Text text = new Text (shell, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL);

        System.out.println("text   " + i);

}

         这段代码在执行第9987次的时候,出现了 Exception in thread "main" org.eclipse.swt.SWTError: No more handles

        

         通过上述可知No more handles 很容易重现,原因也很清楚:句柄不够用,Rule2有部分意思是说如何释放占用的句柄。

Rule2: 在一个Editor打开的代码中,插入代码:

         for (int i = 0; i< 4600; i++) {

        Text text = new Text (shell, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL);

        System.out.println("text   " + i);

}

         当第一次尝试打开editor的时候,没有问题;

第二次尝试打开,也没有问题;(此时有两个Editor窗口实例)

第三次,提示”No more handles”;

关闭第一个窗口,再尝试打开第三个,此时没有问题。

说明,关闭第一个editor后,editor中的(子)资源得以释放。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值