先启动Optimizeit Suite中的profiler模块:
图5 启动Profiler模块
图6 在Profiler主界面中添加新Setting
注意使用Borland Optimizeit Suite时,jar中要把main class设好,classpath中要把所有用到的外部jar包全部输入,否则无法启动和正常运行。这个工具不太友好,无法启动时输出信息很不明确,所以最好自己先检查清楚了。
图7 在Profiler的Setting中设置main class和classpath
一般测试时都有运行多次,当发现某些包跟问题无关时,可以把它们过滤掉,这样最后得到的结果更容易阅读。
图8 设置filter
用Profiler启动程序。运行到问题模块后,点击工具栏最右边的按钮,标记当时各对象占用内存的情况。
图9 标记当前内存情况(图中红柱上的黑线)
点击工具栏上像感叹号的按钮,选择显示的内容。对这个问题,我觉得show size是最重要的。
图10 设置显示的内容
再运行一段时间后,按Size diff排序。发现占用内存比较多的了后,双击该行,打开该对象的详细信息(目前bug已经改好,我只是随便点一个类作为示范)。这时展开整棵树,就可以看到该类所有实例分别是在什么方法中生成的(如果跟踪CPU信息,也有这种资源分配树显示)。
图11 某个类的所有对象的构造位置分布
因为占用内存最多的往往是系统基本数据类型,例如char,int[]等等,所以需要人工去判断哪些类是真正的疑点。我发现占用新申请内存排名第20-30之间有几个类的对象数是完全相同的,而且持续同步增长,估计是某些线程中重复构造对象造成的,比其他以不规则速度增长的类更加可疑,于是就仔细检查了这几个的类的详细信息,发现果然是来自同一个函数。再仔细看代码,就找到内存泄漏的原因,原来是某行代码写错了,不断构造新的button。而保存这些button是用Vector!说明我最早使用的检查HashMap的思路是对的。可惜只是从自己的编程习惯出发,没有考虑到Vector,否则问题就更容易发现了。
文章来源于领测软件测试网 https://www.ltesting.net/