内存泄露排查

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/kdsrpg/article/details/51036450

内存正确释放的原理

前提:只考虑引用计数法

1、FLASH存在垃圾回收机制(GC)

2、GC在没有任何人引用该数据的时候则会对该数据的内存回收

3、当所有引用它的人也被内存回收了,即使没有断开这些引用,仍然会被回收

例如:

var bmp:Bitmap = new Bitmap();
bmp.bitmapData = new BitmapData(100,100,false,0);

bmp的bitmapData只被bmp引用,如果这只是临时作用一下,没有任何外部引用bmp的话(当然添加到显示列表也算被引用了,至少别人能够通过这种方法找到你)就会被回收,当然那个bitmapData也会被回收,因为除了bmp外没有任何人能够找到这个bitmapData了,在这种情况下 bitmapData即使不调用dispose也没有关系。


可访问 --A引用线--> bitmap --B引用-->  bitmapData --C引用线-->位图数据源


1、我们的bitmapData在dispose后会将切断C引用线,然后位图数据源就没有人能够找到,这个时候就释放了大部分资源,因为类没有占用多少内存空间,位图的图片信息占用的很大,在这里相对而言即使造成内存泄露也仅是bitmap和bitmapdata的内存泄露,并不多相对而言会好一些。

2、我们又将B引用线切断,这个时候bitmapData这个实例也无法被访问到了将会被释放。

3、我们又将A引用线切断,这个时候bitmap这个实例也无法被访问到了将会被释放。

所以从安全的排序中看来,将所有线切断是最理想的:

bmp.bitmapData.dispose();
bmp.bitmapData=null;
外部引用bmp = null;

但从效率上来说,如果你能确保只有一处地方引用了该bmp,只切断它,效率会更高
外部引用bmp = null

如果你这个外部引用是某个类实例的一个属性,你也不用切断这个实例里的bmp引用了,你可以直接切断对这个类实例的引用
引用这个类实例的变量 = null


一种排查内存泄露的解决方案

1、根据上面得知一个数据没有被释放无非就是有实例的属性引用了它或类的静态属性引用了它,我们可以抓出这些数据来分析
2、只要自定义类会有实例创建出来的都要有一个释放的方法,例如叫做dispose,你可以为它们创建一个通用的接口。
3、在每个这些类被实例化的时候建立一下对它的引用,在释放的时候清空列表引用,方便你知道当前还被占用的有多少个,分别是哪些
4、建立一个全局队列,将所有自定义类加入进来(包括包外类),方便监控静态属性
5、如果担心造成不必要的性能开销可以在DEBUG模式下才做这些事。


当然如果一个项目大了,内容多了,开发者也多了各不统一,中途去建这样的程序并不理想,因为这是约定要不使用就要dispose或者建立对象池之类的丢回去,
此时可以考虑重构,如果没有时间重构的话就要多依赖flashbuilder的概要分析或者scout工具之类的了。





展开阅读全文

没有更多推荐了,返回首页