`

[转]位图数据内存优化

阅读更多

最近协助同事对Flash相册项目做了程序优化,觉得每个优化步骤的试验结果都挺有价值,所以在这里做一个记录分享。

项目现状
Flash相册程序,在播放60张图片后(60是相册图片数量上限),内存占用接近1G。

当前技术实现
使用Loader加载图片文件,然后新建BitmapData对Loader进行draw*作保存位图数据,随后loader.unload()释放原始图片资源。播放某一张图片时,取出对应的位图数据,根据当前播放窗口大小进行平滑缩放,随后生成Bitmap对象,展现。

优化思考1:所有已加载的图片都保存其位图数据,导致内存占用过大。那么可以考虑**位图数据对内存的占用总量,如果位图数据内存占用超出一个设定值(比如200MB)后销毁离当前播放index最远的图片位图数据。
问题:由于已加载数据可能会被销毁,所以会经常发生图片需要再次加载的情况,影响相册观看流畅度。另外,通过测试发现,即使设定一个比较宽松的上限值(比如200MB),也只能容纳几张图片的位图数据。
该方法损失了用户体验,但问题仍然没有得到较好解决。

优化思考2:BitmapData位图数据占用内存过大,如果Loader加载图片文件后不转化为位图数据,而直接保存loader对象,会不会减小内存占用?
经过试验发现,一个1280*800的jpg(130K),通过Loader加载进舞台并显示,不做任何处理,内存占用高达4MB。将loader对象从舞台上remove掉,只保留引用,内存占用仍不见减少。同时此做法会带来一个问题,loader对象的直接缩放会产生锯齿,这对相册程序而言是不可以接受的。
此路不通。

优化思考3:既然直接保存BitmapData对象很吃内存,那么我通过JPGEncoder将其转化为ByteArray再进行保存,势必会减少开销。需要使用图片时,再通过loader.loadBytes来加载ByteArray数据。
经过试验发现,经过JPGEncoder转化后的ByteArray数据很小,只占用几十KB内存,效果明显。使用loader.loadBytes加载ByteArray显示也很顺利很流程。但一个致命的问题出现了,JPGEncoder执行效率非常低下,即使只是宽高1280*800的BitmapData,转化过程也会长达6秒之久(我的机器配置不低),更糟糕的是,由于Flash是单线程运行环境,所以此*作会导致整个界面卡住,程序陷入假死状态。
(延伸阅读:使用Vector优化JPGEncoder执行效率    异步JPGEncoder)

优化思考4:经Laan提醒,想到ByteArray不需要通过对BitmapData数据JPGEncode来做,通过URLLoader指定BINARY方式读取图片文件,其data属*就是JPG或者其它压缩格式的ByteArray数据。
试验通过,问题终于得到顺利解决。

优化效果
经过上述优化,60张图片播放后,内存占用仍然不到100M,优化效果显著。

最后,说一下如何强制Player进行垃圾回收
如果只想在Debug Player中使用,则可以使用System.gc();
如果想在所有运行环境都能运行,则可以使用下面这一段垃圾回收触发代*(查看原帖):

try {
    new LocalConnection().connect(“gcHacker”);
    new LocalConnection().connect(“gcHacker”);
} catch (e:Error) {
}

分享到:
评论
2 楼 hanshuai1232000 2013-08-02  
第四点,有利也有弊,等你做了大型的aprg,你就知道了
1 楼 ttianyaren 2011-04-08  
这个最近正好需要,谢谢您的分享

相关推荐

    flash动画优化——位图淘汰机制

    综合以上特性,我们可以使用Bitmap将矢量图动画缓存为位图动画,多个相同的对象共用同一份BitmapData数据,这样既可以大幅降低cpu占用,又可以节省内存,同时还避免了直接在库里面使用图片而造成flash文件变大的...

    论文研究-位图连接索引服务机制研究.pdf

    位图连接索引是数据仓库中一种有效的优化表间连接操作性能的索引机制。在大内存分析处理应用场景下,位图连接索引不仅需要权衡索引的内存和CPU开销,还需要进一步考虑处理器平台所带来的性能收益和数据访问延迟。...

    BitmapToBinary:从位图列表生成二进制文件。 它的编写是为了优化从 MCU 内存到基于 PCD8544 控制器的诺基亚 51103310 显示器的数据传输

    编写它是为了优化从 MCU 存储器到基于 PCD8544 控制器的诺基亚 5110/3310 显示器的数据传输。 这只是一个快速修复,还有很多需要修复和改进。 仅以如何在C#中处理位图中的单个像素为例。用法将 bmp 文件放在与 .exe...

    roaringbitmap:Cython中咆哮的位图

    咆哮的位图是一种有效的压缩数据结构,用于存储一组整数。 咆哮位图将一组32位整数存储在一系列数组和位图中,以空间最小的方式(始终为2 ** 16位或更小)。 此数据结构可用于存储大量整数,例如,用于搜索引擎和...

    ORACLE9i_优化设计与系统调整

    §6.2.7 步骤7:优化内存分配 88 §6.2.8 步骤8:优化I/O和物理结构 89 §6.2.9 步骤9:优化资源争用 89 §6.2.10 步骤10:优化所采用的平台 89 §6.3 应用优化方法 90 §6.3.1 设定明确的优化目标 90 §6.3.2 创建...

    column:Go 中具有位图索引的高性能列式内存存储

    带位图索引的列式内存存储该软件包包含一个高性能、柱状、内存中存储引擎,支持快速查询、更新和迭代,零分配和位图索引。特征优化的、缓存友好的列式数据布局,可最大限度地减少缓存未命中。 针对查询期间的零堆...

    Moshidraw2013.1中文简体免费版

    具有常用的贝塞尔曲线、样条曲线、群组、结合、位图矢量化、支持粘贴板和其它程序传递位图数据,可导入DXF、AI、PLT、BMP/JPG/WMF等格式文件,支持导出BMP/JPG图像, 支持打印输出,支持激光雕刻机输出。 优化显示...

    编程珠玑之位图排序

    没有其他数据与该整数关联。 输出:按升序排列的输入整数列表。 约束:最多有(大约)1MB的内存空间可用,有充足的磁盘存储空间可用。运行时间最多几分钟,运行时间为10秒就不需要进一步优化了。

    超级模块5.0完美破解加强版

    ' 优化在Win7或较新显卡驱动的系统中所有位图操作类及识图类均支持DirectX窗口后台截图,旧系统暂不支持 ' 修正"保存对话框"的返回文件名自动加入索引后缀 ' 修正"监视热键","监视热键2","监视热键3","监视热键4",当...

    (E文)基于成本的Oracle优化法则.pdf

    13.1.1 内存的使用 329 13.1.2 CPU的使用 330 13.1.3 sort_area_retained_size 333 13.1.4 pga_aggregate_target 334 13.1.5 实际I/O 337 13.2 排序的成本 339 13.3 比较 343 13.4 归并连接 346 13.4.1 归并机制 347...

    精易编程助手3.3+精易模块v6.3.1

    1、新增“剪辑板_取位图数据A”,“剪辑板_取位图数据B”,感谢【@铅笔刀 】反馈并建议 2、新增“文本_取出文本中汉字”,取出指定文本中的汉字; 3、新增“网页_JS格式化EX”原有的JS格式化命令的升级版; 4、新增...

    易语言-Gdi内存画板10.0

    ◆内存画板新增 图片优化模式()、合并分层画板()、空间坐标变换() ◆新增类“分层画板”,透明画板,更加丰富的画笔画刷设置 类“图片对象”增加了 转换分层画板() 6.0到7.0版本:修复部分bug ◆分层画板增加了 ...

    Gdi内存画板7.0-易语言

    ◆内存画板新增 图片优化模式()、合并分层画板()、空间坐标变换() ◆新增类“分层画板”,透明画板,更加丰富的画笔画刷设置  类“图片对象”增加了 转换分层画板() 6.0到7.0版本:修复部分bug ◆分层画板增加了...

    Gdi内存画板10.0-易语言

    ◆内存画板新增 图片优化模式()、合并分层画板()、空间坐标变换() ◆新增类“分层画板”,透明画板,更加丰富的画笔画刷设置  类“图片对象”增加了 转换分层画板() 6.0到7.0版本:修复部分bug ◆分层画板增加了...

    Gdi内存画板8.0-易语言

    ◆内存画板新增 图片优化模式()、合并分层画板()、空间坐标变换() ◆新增类“分层画板”,透明画板,更加丰富的画笔画刷设置  类“图片对象”增加了 转换分层画板() 6.0到7.0版本:修复部分bug ◆分层画板增加了...

    GDI内存画板_6.0-易语言

    内存画板,在内存中创建一个画板并画图。...◆内存画板新增 图片优化模式()、合并分层画板()、空间坐标变换() ◆新增类“分层画板”,透明画板,更加丰富的画笔画刷设置  类“图片对象”增加了 转换分层画板()

    易语言 茶凉专用模块

    模块名称:茶凉专用模块 作者:茶凉 版本:2.0 本模块可以编程更简单...子程序 读内存长整数型, 长整数型, 公开, 从内存中读取长整数型数据,失败返回失败内容 .参数 进程ID, 整数型, , 进程ID .参数 地址, 整数型, , ...

    delphi 开发经验技巧宝典源码

    0132 从已有的位图上创建位图 86 0133 使用Frame3D过程在画布上创建3D效果 87 4.9 文件操作的相关函数 87 0134 使用CopyFile函数复制文件 87 0135 使用CreateDir函数创建一个目录 88 0136 使用FileCreate...

Global site tag (gtag.js) - Google Analytics