问题
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 Handles
on Windows.
How might this be done?
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>
回答1:
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
来源:https://stackoverflow.com/questions/58627739/accessing-the-current-processes-handles