2

In our RCP 4 application we have had SWT exceptions thrown caused by there being no more handles available. This could be caused by a resource leak or by other 3rd party applications running. We are unable to reproduce this in development so we would like to log any information that could possibly help us fix this in the future.

We would like to get information about the handles. E.g. Total handles and what they are used for such as images, fonts, and composites.

I've been looking this up and I'm struggling to find anything on how this can be done in Java. We could execute command line for the information but that doesn't feel like a great way of doing it.

By Handles I'm referring to GDI Handles and User Handleson Windows.

How might this be done?

Handles

plugin.xml

<plugin>
   <extension
         id="product"
         point="org.eclipse.core.runtime.products">
      <product
            application="org.eclipse.e4.ui.workbench.swt.E4Application"
            name="appid">
         <property
               name="modelResourceHandler"
               value="bundleclass://a.model.resource.handler.ModelResourceHandler">
         </property>
      </product>
   </extension>
</plugin>
Michael
  • 3,411
  • 4
  • 25
  • 56
  • What a 'handle' is and what the limits are vary enormously depending on the Platform you are running on. – greg-449 Oct 30 '19 at 14:51
  • I've updated the question. I mean GDI and User handles on Windows OS. – Michael Oct 30 '19 at 16:01
  • For an RCP using the 3.x compatability layer you could use something like Eclipse Sleak (described in [this tutorlal](https://www.vogella.com/tutorials/EclipsePerformance/article.html)). For an e4 RCP I don't know of anything. – greg-449 Oct 30 '19 at 16:41
  • @greg-449 Unfortunately our application is pure e4/RCP 4. How does Sleak access this information? Is it something that could be possible in code? – Michael Oct 30 '19 at 16:57
  • It is a very small bit of code easy to read [see here](https://www.eclipse.org/articles/swt-design-2/sleak.htm). But it relies on the SWT `Display` being created with a `DeviceData` object - which `E4Application` doesn't do. – greg-449 Oct 30 '19 at 17:02
  • You may be able to create your own `org.eclipse.core.runtime.applications` extension point using a class extending `E4Application` to create the `Display` as required. Eclipse bug [496729](https://bugs.eclipse.org/bugs/show_bug.cgi?id=496729) mentions doing this. – greg-449 Oct 30 '19 at 17:11
  • @greg-449 Okay I'll have a look thank you. – Michael Oct 30 '19 at 17:18

1 Answers1

2

Eclipse Sleak can monitor the allocations made by SWT - the code is here.

However this requires the SWT Display to be created with a DeviceData object enabling tracking. The standard E4Application doesn't do this.

So to use this you need to use your own application class extending E4Application - something like:

import org.eclipse.e4.ui.internal.workbench.swt.E4Application;

import org.eclipse.swt.graphics.DeviceData;
import org.eclipse.swt.widgets.Display;

public class MyApplication extends E4Application
{
  /** Enable tracking */
  private static final boolean TRACKING = true;
  /** Enable debug */
  private static final boolean DEBUG = false;

  public MyApplication()
  {
    super();
  }

  @Override
  public Display getApplicationDisplay()
  {
    Display current = Display.getCurrent();
    if (current == null)
     {
       if (TRACKING || DEBUG)
        {
          DeviceData data = new DeviceData();
          data.tracking = TRACKING;
          data.debug = DEBUG;

          current = new Display(data);

          if (data.tracking)
           {
             Sleak sleak = new Sleak();
             sleak.open();
           }
        }
       else
        {
          current = new Display();
        }
     }

    return super.getApplicationDisplay();
  }
}

You will need to declare this application in the plugin.xml:

   <extension
         id="application"
         name="Application name"
         point="org.eclipse.core.runtime.applications">
      <application
            cardinality="singleton-global"
            thread="main"
            visible="true">
         <run
               class="your.package.MyApplication">
         </run>
      </application>
   </extension>

Change your product declaration in the plugin.xml to use this application instead of org.eclipse.e4.ui.workbench.swt.E4Application. So something like:

   <extension
         id="product"
         point="org.eclipse.core.runtime.products">
      <product
            name="%product.name"
            application="my.plugin.application">

As a further example the following is part of a tested, working plugin.xml from one of my e4 RCPs:

<plugin>
   <extension
         id="application"
         name="%app.name"
         point="org.eclipse.core.runtime.applications">
      <application
            cardinality="singleton-global"
            thread="main"
            visible="true">
         <run
               class="greg.music.e4.rcp.MusicApplication">
         </run>
      </application>
   </extension>
   <extension
         id="product"
         point="org.eclipse.core.runtime.products">
      <product
            name="%product.name"
            application="greg.music.e4.rcp.application">
            ...... properties
       </product>
   </extension>

This is in a plugin with id greg.music.e4.rcp. This defines an application with id greg.music.e4.rcp.application and a product with id greg.music.e4.rcp.product

greg-449
  • 109,219
  • 232
  • 102
  • 145
  • How can this be done in the `plugin.xml` if it is a product? I've updated my question to show a cut down example of ours. I've tried changing the `application` to be the custom one but an error is thrown `Application "my.custom.E4Application" could not be found in the registry`. I've also tried adding cardinality, thread, and visible attributes. – Michael Oct 31 '19 at 10:23
  • Looks like the application id is probably wrong. The application id is the value of the `id` parameter in the org.eclipse.core.runtime.applications `extension` with the plug-in added at the front. So in my example if the plugin id is 'my.plugin' the application id is 'my.plugin.application' – greg-449 Oct 31 '19 at 10:30
  • I think the ID is right I just renamed it incorrectly in the example I gave? I've updated it. I've read over your comment multiple times but I'm getting myself confused. In your example where is the application id set? I'm struggling to see the changes I need to my plugin.xml to do this. – Michael Oct 31 '19 at 11:10
  • It is defined by the `id="application"` in the second line of the 'org.eclipse.core.runtime.applications' 'extension'. The id then needs to be used the `product` `application` - see updated example. Note that the application id is not the Java class name. – greg-449 Oct 31 '19 at 11:16
  • That was it. Thank you for the extra examples they really helped! – Michael Oct 31 '19 at 11:59