flash垃圾回收和内存泄露
2011-11-15 11:44
246 查看
GC的原子模型
之所以用"原子模型"(Atomic Model)这个词,是因为这篇文章是用来描述GC怎么样在player中工作的模型,但是不包涵其相关的技术实现或细节描述。
之所以这样是因为:
1.GC在实际中的运行行为甚为复杂并且很难区描述(就像我们其实并不知道原子是什么构成的,但是我们却可以用模型来解决问题)
2.player有时会干预GC
3.这个模型已经为我工作了很久了
Flash Player 内存管理
Flash持有的内存块被分配成很多等量的小内存块
flash会一次向操作系统申请几大块儿内存(所以flash不会经常向系统申请内存)
在flash中把从操作系统申请的一大块内存作为一个内存池,然后将内存池分割成包含很多很小且大小固定的块(block).
大的块用来存储Bitmap,文件等内存大户,而且他们是不可合并的
下载
(62.46 KB)
2010-9-7 15:37
当一个内存池用完时,flash会向操作系统再申请一大块内存.
下载
(25.85 KB)
2010-9-7 15:37
GC并不是总在运行
你不知道什么时候会垃圾回收
当某些对象被释放后,他们在内存中所占用的块(block)并不一定在下一次分配内存时被重用.
假设我们当前内存使用大小为100000bytes
下载
(31.92 KB)
2010-9-7 15:37
假设Foo实例大小为 512bytes
当分配内存时,它会占用flash内存池中新的一个512bytes单元
foo = new Foo()
下载
(32.95 KB)
2010-9-7 15:37
当我们清除一个对象所有引用后,此时对象占用的内存并没有立即被标记为未使用,只有GC将其标记为未使用后,该对象所占用的块属性才会变为未使用.
内存仍然为100512 bytes.
将其置空(销毁)并不代表其在内存中已经被释放.
System.totalMemory = 100512 bytes
下载
(38.93 KB)
2010-9-7 15:37
我们再次实例化一个新的Foo对象,它会占用flash内存池中新的单元(未使用的单元)
内存现在是101024 bytes.
下载
(42.76 KB)
2010-9-7 15:37
只有内存分配才会引发垃圾回收.
当一个内存池快被用完时,在向操作系统申请内存之前前,GC就会尝试去收集内存池.
就像影片租赁一样,他们不会去检查最近还回来的影片,而是要等货架上所有的影片都没了的时候才会去检查.
下载
(39.92 KB)
2010-9-7 15:37
只能被内存分配才会引发GC;这就意味着,你总可以在内存中看到一些未被回收的对象,并且它们一直占用内存.
GC回收一次内存并不一定会将所有的可回的对象全部回收
因此不要企图通过渲染或者交互来干预GC
这就意味内存永远不可能回复到最初的状态.
下载
(49.09 KB)
2010-9-7 15:37
下载
(49.66 KB)
2010-9-7 15:37
收集器会尽量将所有标记为"未使用"的块儿整理到同一个flash内存池中,当某一个flash内存池中所有小的单元都是"未使用"时,flash就会将其释放,返还给操作系统.
一般情况下GC不会一次就完成这一过程(译者注:在ActionScript 3.0 and
AVM2
erformance Tuning这篇文章中提及每次标记时间限制在30毫秒内).
因此内存永远都不可能恢复到出事状态.
下载
(29.63 KB)
2010-9-7 15:37
下载
(42.57 KB)
2010-9-7 15:37
由于GC是不可确定的,这就意味着你不能严格的确认你的程序是否出现了内存泄露
但是我们可以靠经验来判断。检测内存泄露
一些不起眼的事件例如timing事件,鼠标事件和键盘事件都会影响总内存。
因此交互不是一个很好的检测方法.
一般情况我们可以关注一些可重复的过程
popup对话窗口生成和删除
Modules的加载和卸载
如果在一段时间内重复执行这一过程,那么内存总量会在达到某个最高值后停止或者下降,当然前提是你的程序没有内存泄露
在flex下一次释放内存时, 就会知道否有有内存泄露的症状.
在此之前:
编写as代码使其过程自动化,即使整体流程的执行不依赖于交互.
其中一种技术就是使用switch语句并伪造鼠标和键盘事件
private function doit():void { // call this on some interval
var m:MouseEvent;
switch (currentStep)
{
case 0:
m = new MouseEvent(MouseEvent.CLICK);
b.dispatchEvent(m); // click app button to open dialog
break;
case 1:
case 2:
// wait for dialog to appear
break;
case 3:
m = new MouseEvent(MouseEvent.CLICK);
var o:Object = loginDialog;
o.b.dispatchEvent(m); // click dialog button to close dialog
case 4:
case 5:
break;
default:
currentStep = -1; // start over again
break;
}
currentStep++;
}
复制代码
去哪里找内存泄流的源头
( 原文:They will get reassigned every time through the sequence so they will drop their reference to the previous object )
1.对于一个可重复的过程, 属性引用到的对象是不会造成内存泄露的
因为每一次的执行,他们都会被重新赋值.
( 原文:Arrays, Objects used as Maps, Dictionary are common causes )
2.把Array,Objects当做Maps,Dictionnary来用,可能会引起内存泄露
(原文 : Run the sequence once, see how many things are in the arrays and object maps)
运行一次该过程,看array 或 object maps存有多少个对象
( 原文: Run it several more times, are there more things? )
运行多次再观察它们所包含的对象数量
3.没有移除监听器
GC怎样工作的
(原文:Start at known tops of Object trees. )
从已知的对象树(Object trees)的顶开始
(原文:Mark them and any objects they reference)
1.标记当前"节点"所有引用到的对象
(原文: Go through the heap and free anything that isn’t marked.)
2.检查堆,"释放"没有被标记的对象.
(Three tops of Object trees
3.对象树的3种顶层类型
(Stage)
Sttage
(ApplicationDomain/Class definitions)
ApplicationDomain/类定义(Class definitions)
(Stack/Local Variable)
栈/本地变量
Stage
从 Stage开始你可以跟随箭头(引用)找到所有的蓝色盒子(被使用对象)
下载
(53.03 KB)
2010-9-7 16:07
ApplicationDomain/Class definitions
只有静态变量会产生影响
下载
(63.29 KB)
2010-9-7 16:07
栈(stack)/本地变量(Local Variables)
下载
(68.16 KB)
2010-9-7 16:08
移除监听器
对子容器添加监听器不会引起内存泄露
下面的监听器不强制要求移除(但是移除所有监听器是一个好习惯)
下载
(73.12 KB)
2010-9-7 16:08
子容器的监听列表会保存一个父级容器事件处理函数的引用
当子容器被从父级容器中移除后,就不可能通过Stage访问到了
下载
(47.06 KB)
2010-9-7 16:08
监听父级对象时会造成内存泄露
必须要移除对父级容器的监听器
下载
(57.23 KB)
2010-9-7 16:08
有两种2个路径可以到达PopUp
下载
(59.33 KB)
2010-9-7 16:08
在这里使用弱引用可能会会更好些
除非你可以确认你和你的父级已经从显示列表中删除了.
下面的监听器不强制要求删除。
下载
(72.65 KB)
2010-9-7 16:08
总结
1..GC是内存分配引起的而非程序中的删除
2.GC时不可预测的
3.使可重复过程自动化
随着时间的推移,总内存应该会有一个最大值.
4.出乎你意料的是:事件监听会造成反向引用.
Dispatcher引用监听器
例子代码
原文ppt
之所以用"原子模型"(Atomic Model)这个词,是因为这篇文章是用来描述GC怎么样在player中工作的模型,但是不包涵其相关的技术实现或细节描述。
之所以这样是因为:
1.GC在实际中的运行行为甚为复杂并且很难区描述(就像我们其实并不知道原子是什么构成的,但是我们却可以用模型来解决问题)
2.player有时会干预GC
3.这个模型已经为我工作了很久了
Flash Player 内存管理
Flash持有的内存块被分配成很多等量的小内存块
flash会一次向操作系统申请几大块儿内存(所以flash不会经常向系统申请内存)
在flash中把从操作系统申请的一大块内存作为一个内存池,然后将内存池分割成包含很多很小且大小固定的块(block).
大的块用来存储Bitmap,文件等内存大户,而且他们是不可合并的
下载
(62.46 KB)
2010-9-7 15:37
当一个内存池用完时,flash会向操作系统再申请一大块内存.
下载
(25.85 KB)
2010-9-7 15:37
GC并不是总在运行
你不知道什么时候会垃圾回收
当某些对象被释放后,他们在内存中所占用的块(block)并不一定在下一次分配内存时被重用.
假设我们当前内存使用大小为100000bytes
下载
(31.92 KB)
2010-9-7 15:37
假设Foo实例大小为 512bytes
当分配内存时,它会占用flash内存池中新的一个512bytes单元
foo = new Foo()
下载
(32.95 KB)
2010-9-7 15:37
当我们清除一个对象所有引用后,此时对象占用的内存并没有立即被标记为未使用,只有GC将其标记为未使用后,该对象所占用的块属性才会变为未使用.
内存仍然为100512 bytes.
将其置空(销毁)并不代表其在内存中已经被释放.
System.totalMemory = 100512 bytes
下载
(38.93 KB)
2010-9-7 15:37
我们再次实例化一个新的Foo对象,它会占用flash内存池中新的单元(未使用的单元)
内存现在是101024 bytes.
下载
(42.76 KB)
2010-9-7 15:37
只有内存分配才会引发垃圾回收.
当一个内存池快被用完时,在向操作系统申请内存之前前,GC就会尝试去收集内存池.
就像影片租赁一样,他们不会去检查最近还回来的影片,而是要等货架上所有的影片都没了的时候才会去检查.
下载
(39.92 KB)
2010-9-7 15:37
只能被内存分配才会引发GC;这就意味着,你总可以在内存中看到一些未被回收的对象,并且它们一直占用内存.
GC回收一次内存并不一定会将所有的可回的对象全部回收
因此不要企图通过渲染或者交互来干预GC
这就意味内存永远不可能回复到最初的状态.
下载
(49.09 KB)
2010-9-7 15:37
下载
(49.66 KB)
2010-9-7 15:37
收集器会尽量将所有标记为"未使用"的块儿整理到同一个flash内存池中,当某一个flash内存池中所有小的单元都是"未使用"时,flash就会将其释放,返还给操作系统.
一般情况下GC不会一次就完成这一过程(译者注:在ActionScript 3.0 and
AVM2
erformance Tuning这篇文章中提及每次标记时间限制在30毫秒内).
因此内存永远都不可能恢复到出事状态.
下载
(29.63 KB)
2010-9-7 15:37
下载
(42.57 KB)
2010-9-7 15:37
由于GC是不可确定的,这就意味着你不能严格的确认你的程序是否出现了内存泄露
但是我们可以靠经验来判断。检测内存泄露
一些不起眼的事件例如timing事件,鼠标事件和键盘事件都会影响总内存。
因此交互不是一个很好的检测方法.
一般情况我们可以关注一些可重复的过程
popup对话窗口生成和删除
Modules的加载和卸载
如果在一段时间内重复执行这一过程,那么内存总量会在达到某个最高值后停止或者下降,当然前提是你的程序没有内存泄露
在flex下一次释放内存时, 就会知道否有有内存泄露的症状.
在此之前:
编写as代码使其过程自动化,即使整体流程的执行不依赖于交互.
其中一种技术就是使用switch语句并伪造鼠标和键盘事件
private function doit():void { // call this on some interval
var m:MouseEvent;
switch (currentStep)
{
case 0:
m = new MouseEvent(MouseEvent.CLICK);
b.dispatchEvent(m); // click app button to open dialog
break;
case 1:
case 2:
// wait for dialog to appear
break;
case 3:
m = new MouseEvent(MouseEvent.CLICK);
var o:Object = loginDialog;
o.b.dispatchEvent(m); // click dialog button to close dialog
case 4:
case 5:
break;
default:
currentStep = -1; // start over again
break;
}
currentStep++;
}
复制代码
去哪里找内存泄流的源头
( 原文:They will get reassigned every time through the sequence so they will drop their reference to the previous object )
1.对于一个可重复的过程, 属性引用到的对象是不会造成内存泄露的
因为每一次的执行,他们都会被重新赋值.
( 原文:Arrays, Objects used as Maps, Dictionary are common causes )
2.把Array,Objects当做Maps,Dictionnary来用,可能会引起内存泄露
(原文 : Run the sequence once, see how many things are in the arrays and object maps)
运行一次该过程,看array 或 object maps存有多少个对象
( 原文: Run it several more times, are there more things? )
运行多次再观察它们所包含的对象数量
3.没有移除监听器
GC怎样工作的
(原文:Start at known tops of Object trees. )
从已知的对象树(Object trees)的顶开始
(原文:Mark them and any objects they reference)
1.标记当前"节点"所有引用到的对象
(原文: Go through the heap and free anything that isn’t marked.)
2.检查堆,"释放"没有被标记的对象.
(Three tops of Object trees
3.对象树的3种顶层类型
(Stage)
Sttage
(ApplicationDomain/Class definitions)
ApplicationDomain/类定义(Class definitions)
(Stack/Local Variable)
栈/本地变量
Stage
从 Stage开始你可以跟随箭头(引用)找到所有的蓝色盒子(被使用对象)
下载
(53.03 KB)
2010-9-7 16:07
ApplicationDomain/Class definitions
只有静态变量会产生影响
下载
(63.29 KB)
2010-9-7 16:07
栈(stack)/本地变量(Local Variables)
下载
(68.16 KB)
2010-9-7 16:08
移除监听器
对子容器添加监听器不会引起内存泄露
下面的监听器不强制要求移除(但是移除所有监听器是一个好习惯)
下载
(73.12 KB)
2010-9-7 16:08
子容器的监听列表会保存一个父级容器事件处理函数的引用
当子容器被从父级容器中移除后,就不可能通过Stage访问到了
下载
(47.06 KB)
2010-9-7 16:08
监听父级对象时会造成内存泄露
必须要移除对父级容器的监听器
下载
(57.23 KB)
2010-9-7 16:08
有两种2个路径可以到达PopUp
下载
(59.33 KB)
2010-9-7 16:08
在这里使用弱引用可能会会更好些
除非你可以确认你和你的父级已经从显示列表中删除了.
下面的监听器不强制要求删除。
下载
(72.65 KB)
2010-9-7 16:08
总结
1..GC是内存分配引起的而非程序中的删除
2.GC时不可预测的
3.使可重复过程自动化
随着时间的推移,总内存应该会有一个最大值.
4.出乎你意料的是:事件监听会造成反向引用.
Dispatcher引用监听器
例子代码
原文ppt
相关文章推荐
- Android垃圾回收机制解决内存泄露问题
- Flash/Flex垃圾回收问题(解决方案汇总)
- Flash务实主义(五)——AS3的垃圾回收
- 浅谈Flash的垃圾回收机制
- flash开发中提高性能方法的整理-------------垃圾回收机制的总结
- java垃圾回收和内存泄露的讲解
- Flash AS 3.0垃圾回收
- java垃圾回收机制、内存泄露
- Flash强制垃圾回收
- [ JS 进阶 ] 闭包,作用域链,垃圾回收,内存泄露
- 深入解析PHP垃圾回收机制对内存泄露的处理
- flash开发中提高性能方法的整理-------------垃圾回收机制的总结
- 发现一篇关于flash垃圾回收机制的文章
- 【Flash 务实主义】AS3的垃圾回收
- flash的强制垃圾回收 flash内存释放
- C指针原理(49)-垃圾回收-内存泄露
- AS3垃圾回收及内存泄露处理
- 简析Android的垃圾回收与内存泄露
- flash 垃圾回收GC
- PHP内存泄露与垃圾回收