这是对AS3进行BitmapData内存分配的简单测试。
private function memoryTest(): void
{
trace("BitmapData memory test. Create bmps..."); // First breakpoint
var bmps:Array = new Array (1000);
for (var i:int=0; i<1000; i++)
{
bmps[i] = new BitmapData(451, 451, true, 0);
trace(i+". bmp created");
}
trace("All bmps created."); // Second breakpoint
for (i=0; i<1000; i++)
{
bmps[i].dispose();
bmps[i] = null;
}
bmps.splice(0, bmps.length);
bmps = null;
freeMemoryGC();
trace("All bmps deleted.");
trace("Test complete."); // Last breakpoint
}
private function freeMemoryGC(): void
{
// the GC will perform a full mark/sweep on the second call.
try
{
new LocalConnection().connect('foo');
new LocalConnection().connect('foo');
}
catch (e:*)
{
}
System.gc();
System.gc();
}
此测试中有3个断点,在代码中有注释。断点在一段时间内暂停程序。断点对应于此内存状态图表上的水平线。
我的问题是:为什么在 dispose()调用后,所有内存都没有空闲?这段代码有什么问题,以及如何正确清除 BitmapData 对象?
更新1 : 我认为这个问题不在垃圾收集器中。 dispose()在GC之外运行,它应该释放像素数据。此示例还应在理论上分配451 * 451 * 4 * 1000字节 。但是这个测试应用程序在 System.privateMemory 中分配了 25%以上字节,并且GC和 dispose()从未发布这25%。
更新2 : 如果我创建13个图像4059x4059像素而不是100个图像451x451像素,那么在调用GC之后,内存分配正好等于理论大小并且内存正确释放!我不知道为什么会这样。
UPDATE3 : 这是我的间隔测试结果,由Daniel MesSer在他的回答中创建:
答案 0 :(得分:0)
尝试在free memorygc-function中删除有关本地连接的内容。这解决了吗?
修改强>
package nyx_gaming_group.as3_tests {
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.system.System;
import messer_entertainment.MesSerUtils;
/**
* ...
* @author Daniel Dahlkvist
*/
public class BitmapDataMemoryLeak extends Sprite {
private var _bitmaps:Array;
public function BitmapDataMemoryLeak() {
run();
}
private function run():void {
MesSerUtils.delayCall(createBitmaps, 150);
MesSerUtils.delayCall(destroyBitmaps, 4500);
MesSerUtils.delayCall(freeMemoryGC, 4700);
MesSerUtils.delayCall(run, 8000);
}
private function createBitmaps():void {
trace("BitmapData memory test. Create bmps..."); // First breakpoint
_bitmaps = new Array(1000);
for (var i:int = 0; i < 1000; i++) {
_bitmaps[i] = new BitmapData(451, 451, true, 0);
}
trace("All bmps created."); // Second breakpoint
}
private function destroyBitmaps():void {
for (var i:int = 0; i < _bitmaps.length; i++) {
_bitmaps[i].dispose();
_bitmaps[i] = null;
}
_bitmaps = null;
trace("All bmps deleted.");
trace("Test complete."); // Last breakpoint
}
private function freeMemoryGC():void {
System.gc();
}
}
}