SWT应用内存泄漏Sleak分析
发布者:
YunShui
Sleak 是一个用于检测 SWT 图形资源的简单工具,它能探测到 SWT 应用中资源代码泄露问题。 源码: Sleak.java
简介
在使用此工具前,必须把 Sleak 加入到当前工程 Class Path 中,并找到应用程序代码创建 Display 的地方:
Display display = new Display();
具体步骤如下:
- 在创建 Display 之前,创建一个 DeviceData 并设置 data.tracking 标志为 true 。
- 使用此 DeviceData 创建 Display 。
- 创建 Sleak 实例并调用其 open 方法。
代码示例如下:
DeviceData data = new DeviceData();
data.tracking = true;
Display display = new Display(data);
Sleak sleak = new Sleak();
sleak.open();
运行应用程序代码时, Sleak 也会随之启动,界面如下:
-
Snap 快照当前应用中资源使用情况
-
Diff 比较当前资源和 Snap 资源中使用情况
-
Stack 显示资源堆栈调用
代码示例
RCP 工程代码需修改 Application.java
55 和 56 行为修改 SWT 的 Policy 为 Debug 级别。调用 PlatformUI 的 createDisplay 方法创建 Display 对象,然后创建 Sleak 对象调用其 open 方法。
案例分析
Image 示例
private Image getImage(String imageName) {
Image image = ResourceManager.getPluginImage("com. gui.client.resources",
"icons/sgmt/" + imageName + ".png");
if (!model.isVertical ()) {
return ImageUtil.reducedTo(image,
(int) ((double) image.getBounds().width / 4),
(int) ((double) (image.getBounds().height) / 4));
} else {
Image nImage = ImageUtil.reducedTo(image,
(int) ((double) image.getBounds().width / 6),
(int) ((double) (image.getBounds().height) / 6));
nImage = ImageUtil.reducedTo(image, nImage.getBounds().width,
nImage.getBounds().height * 2, false);
return ImageUtil.rotate(nImage, 90);
}
}
该方法根据 Image 名字和 resource 工程中已保存的图片动态创建所需 Size 的 Image ,实现过程中操作包含动态调整图片大小转换、 Image 的旋转等操作。运行时间和打开关闭频率比较低时问题不大,但这些操作比较频繁时,应用会占用大量的内存,系统反应迟钝。这是因为临时创建的 Image 会一直驻留在系统内存中,直到应用进程退出。此 UI 页面的每一次关闭和重新打开,都会创建这些 Image ,造成 Image 内存持续占用。
解决方案可为:
- 不动态创建 Image ,创建好 Image 放在 resource 工程中,延迟加载。
- 动态创建 Image ,但使用完关闭。
参考实现如下:
private Image getSegmentationImage(String imageName) {
return ImageResource.getImage("icons/sgmt/" + imageName
+ (model.isVertical() ? "_v" : "_h") + ".png");
}
public static final Image getImage(String imagePath) {
Image image = IMAGE_MAP.get(imagePath);
if (image == null || image.isDisposed()) {
image = ResourceManager.getPluginImage("com.gui.client.resources", imagePath);
IMAGE_MAP.put(imagePath, image);
}
return image;
}
Image 采用 Map 来 Cache ,并延迟加载。
GC 、 Color 、 Font 示例
public class ExampleCanvas extends Canvas {
private Color inactiveTabColor = new Color(null, 204, 204, 204);
private Color activeTabColor = new Color(null, 134, 206, 244);
private Color borderColor = new Color(null, 255, 255, 255);
private Color fontColor = new Color(null, 255, 255, 255);
private Font activeFont = null;
private Font inactiveFont = null;
public AdvNavBar(Composite parent, int style) {
// ...
addDisposeListener(new DisposeListener() {
@Override
public void widgetDisposed(DisposeEvent e) {
inactiveTabColor.dispose();
activeTabColor.dispose();
borderColor.dispose();
fontColor.dispose();
}
});
// ...
}
@Override
public Point computeSize(int wHint, int hHint, boolean changed) {
GC gc = new GC(this);
// ...
gc.dispose();
return new Point(width, height);
}
@Override
public void dispose() {
inactiveTabColor.dispose();
activeTabColor.dispose();
borderColor.dispose();
fontColor.dispose();
if (activeFont != null) {
activeFont.dispose();
}
if (inactiveFont != null) {
inactiveFont.dispose();
}
super.dispose();
}
}
示例处理方法为:
- 增加 Dispose 监听回收 Color 资源
- 使用完 GC 调用 GC.dispose() 方法回收 GC
- 覆盖父类 dispose 方法回收 Font 和 Color 资源
总结
SWT 框架内核代码也有资源泄漏问题,所以我们在定义外部资源时更应该做回收处理,以免造成不必要的资源内存消耗。典型情况如下:
ResourceManager.getPluginImage("resources", "icons/error_12x12.png");
GC gc = new GC(this)
Color color = new Color(null, 204, 204, 204);
Font f ont = new Font(null, gc.getFont().getFontData()[0]);
书写代码时应该特别注意。
睿初科技软件开发技术博客,转载请注明出处
blog comments powered by Disqus
发布日期
标签
最近发表
- volatile与多线程
- TDD practice in UI: Develop and test GUI independently by mockito
- jemalloc源码解析-核心架构
- jemalloc源码解析-内存管理
- boost::bind源码分析
- 小试QtTest
- 一个gtk下的目录权限问题
- Django学习 - Model
- Code snippets from C & C++ Code Capsule
- Using Eclipse Spy in GUI products based on RCP
文章分类
- cpp 3
- wxwidgets 4
- swt/jface 1
- chrome 3
- memory_management 5
- eclipse 1
- 工具 4
- 项目管理 1
- cpplint 1
- 算法 1
- 编程语言 1
- python 5
- compile 1
- c++ 7
- 工具 c++ 1
- 源码分析 c++ 3
- c++ boost 2
- data structure 1
- wxwidgets c++ 1
- template 1
- boost 1
- wxsocket 1
- wxwidget 2
- java 2
- 源码分析 1
- 网路工具 1
- eclipse插件 1
- django 1
- gtk 1
- 测试 1
- 测试 tdd 1
- multithreading 1