【发布时间】:2017-11-07 11:50:49
【问题描述】:
我有一个 AIR 应用程序,它可以从 Flash 编辑器呈现图像。您可以自定义多个表面 - 它们都具有相同的宽度和高度。然后每个表面都由 AIR 应用程序渲染。
我正在努力解决我无法解决的内存泄漏问题。
对于我需要渲染的每个表面,我都有一个包含许多组件的 Sprite(其他 sprite - 一些具有事件侦听器、BitmapDatas 和其他子组件、sprite 等)。
我已经知道要被垃圾收集的 BitmapData 问题,我都测试了:
- 为每次渲染创建一个新的 BitmapData 然后 dispose() 并指向 null
- 为每次渲染重复使用单个 BitmapData
内存泄漏仍然以相同的比例发生。
这是我的循环:
var bm:BitmapData = new BitmapData(destDim.x, destDim.y, true, bgColor);
var mtx:Matrix = new Matrix();
trace('before drawing :'+(System.privateMemory/1024));
bm.draw(myBigSprite, mtx, null, null, null, true);
trace('after drawing :'+(System.privateMemory/1024));
var result:Bitmap = new Bitmap(bm, PixelSnapping.NEVER, true);
//return result and encode Bitmap to png
result.bitmapData.dispose();
result.bitmapData = null;
result = null;
结果:
before drawing :208364
after drawing :302816
Wrote bitmap to file: surface0.png
before drawing :303296
after drawing :446160
Wrote bitmap to file: surface1.png
before drawing :446160
after drawing :565212
Wrote bitmap to file: surface2.png
before drawing :565924
after drawing :703100
Wrote bitmap to file: surface3.png
before drawing :703572
after drawing :834420
Wrote bitmap to file: surface4.png
我觉得我在绘制函数行为中遗漏了一些东西。似乎我新创建了 myBigSprite 组件的实例,这些实例在绘制操作后仍然存在。
我试图在每个循环结束时完全销毁 myBigSprite,它不会改变任何东西......
任何提示将不胜感激!
【问题讨论】:
-
你怎么知道垃圾回收进程运行了?你强迫它吗?也只是作为旁注,据我所知,通过调用 System.gc() 强制 gc 仅适用于调试播放器。
-
正如你所见,一个绘制操作结束和下一个开始之间的内存几乎是相等的,但是在这之间有很多内存消耗操作。特别是将位图编码为png。所以我假设 GC 进程正在完成它的工作,因为我想要清理的所有资源都被清理了,除了绘制函数。我从不明确调用 System.gc()。
-
您是否将“结果”设置为 null,因为它包含对位图数据的引用?
-
是的,我编辑了我的 sn-p,因为不清楚,抱歉。
-
@Bedu33 通常情况下,垃圾收集器是惰性的,不会在未使用时立即处理任何未使用的内存。因此,我建议您尝试显式调用 System.gc() 并查看内存测量值。如果这样做可以解决你的问题,那么它不是内存泄漏,它只是 GC 懒惰。
标签: actionscript-3 flash memory-leaks air