创建 StageWebView 的实例时,如果您在多个站点之间切换,您会注意到使用的内存量缓慢增加。如果您正在查看 2/3 的站点,这不是问题,但在使用内置浏览器创建 AIR 应用程序时,我现在在内存管理方面遇到了瓶颈。
无论我做什么
- 每次调用后 StageWebView.dispose()
- 重置阶段
问题依然存在。每加载一个网页都会增加 3mb 的内存,逐渐增加到 1gb 以上并导致应用程序崩溃。
我在 StageWebView 实例上没有事件监听器。我绝对没有提到它。在加载第二个 URL 后,内存并没有完全重置。
这可以通过在 AIR 中运行以下命令看到:
package kazo
{
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Rectangle;
import flash.media.StageWebView;
import mx.controls.Button;
import mx.core.UIComponent;
import flash.system.System;
/**
* ...
* @author KM
*/
public class Controller extends UIComponent
{
private var stageWeb:StageWebView;
private var url:uint = 0;
private const URL_ARRAY:Array = [
'http://www.mmo-champion.com/',
'http://www.bbc.co.uk/news/',
'http://www.twitch.tv/riotgames/',
'http://www.stackoverflow.com/'
]
/**
*
*/
public function Controller()
{
addEventListener(Event.ADDED_TO_STAGE, init);
}
/**
*
* @param e
*/
private function init(e:Event):void {
removeEventListener(Event.ADDED_TO_STAGE, init);
stageWeb = new StageWebView();
stageWeb.stage = stage;
stageWeb.viewPort = new Rectangle(0, 80, width, height - 50);
var btn:Button = new Button();
addChild(btn);
btn.label = 'Load URL';
btn.x = 0;
btn.y = 10;;
btn.width = 100;
btn.height = 30;
btn.addEventListener(MouseEvent.CLICK, load);
btn = new Button();
btn.label = 'Try to GC';
btn.x = 150;
btn.y = 10;;
btn.width = 100;
btn.height = 30;
addChild(btn);
btn.addEventListener(MouseEvent.CLICK, tryGC);
/// 26,576k
}
/**
*
* @param e
*/
private function load(e:MouseEvent):void {
if (!stageWeb) {
stageWeb = new StageWebView();
stageWeb.stage = stage;
stageWeb.viewPort = new Rectangle(0, 80, width, height - 50);
}
stageWeb.loadURL(URL_ARRAY[url % 4]);
url++;
}
/**
*
* @param e
*/
private function tryGC(e:MouseEvent):void {
stageWeb.stage = null;
stageWeb.viewPort = null;
stageWeb.dispose();
stageWeb = null;
System.gc();
}
}
}
有没有人有这方面的经验?
最佳答案
我对您的代码做了一些小改动,使其可以使用 AIR 14 SDK(ASC 2.0,无 flex)进行编译,我构建并测试了 air 应用程序
mxmlc -optimize=true +configname=air Controller.as && adl Controller.xml
并使用 Adobe Scout 观察内存使用情况
GC后内存稳定,稳定在14481kB
您可以将 -advanced-telemetry=true
选项添加到 mxmlc 以精确跟踪分配/取消分配,只需考虑按下“隐藏已清除对象”开关并选择两次 GC 之间的范围。你会看到一些对象没有立即释放,但你也会看到,如果你同时选择其中的几个范围,那些临时泄漏不会加起来,这解释了为什么在 GC 环境中内存不会不断增加, 内存泄漏并不是真正的内存泄漏
如何衡量内存使用情况?
我检查了 adl 进程的内存使用情况,它更高 (> 100MB) 并且不太稳定,但在 GC 之后仍然稳定在 110 到 120MB 之间。无论如何,它看起来绝对不会增加到 1 GB
请记住,ActionScript GC 是惰性的,并保留对象池以供将来重用,任何执行超过 hello world 的应用程序有时都会有奇怪的内存行为,这是 AVM2 工作方式的一部分。
package
{
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Rectangle;
import flash.media.StageWebView;
import flash.system.System;
import flash.text.TextField;
/**
* ...
* @author KM
*/
public class Controller extends Sprite
{
private var stageWeb:StageWebView;
private var url:uint = 0;
private const URL_ARRAY:Array = [
'http://www.mmo-champion.com/',
'http://www.bbc.co.uk/news/',
'http://www.twitch.tv/riotgames/',
'http://www.stackoverflow.com/'
]
/**
*
*/
public function Controller()
{
addEventListener(Event.ADDED_TO_STAGE, init);
}
/**
*
* @param e
*/
private function init(e:Event):void {
removeEventListener(Event.ADDED_TO_STAGE, init);
stageWeb = new StageWebView();
stageWeb.stage = stage;
stageWeb.viewPort = new Rectangle(0, 80, stage.stageWidth, stage.stageHeight - 50);
var btn:TextField = new TextField();
btn.selectable = false;
addChild(btn);
btn.text = 'Load URL';
btn.x = 0;
btn.y = 10;;
btn.width = 100;
btn.height = 30;
btn.addEventListener(MouseEvent.CLICK, load);
btn = new TextField();
btn.selectable = false;
btn.text = 'Try to GC';
btn.x = 150;
btn.y = 10;;
btn.width = 100;
btn.height = 30;
addChild(btn);
btn.addEventListener(MouseEvent.CLICK, tryGC);
/// 26,576k
}
/**
*
* @param e
*/
private function load(e:MouseEvent):void {
if (!stageWeb) {
stageWeb = new StageWebView();
stageWeb.stage = stage;
stageWeb.viewPort = new Rectangle(0, 80, stage.stageWidth, stage.stageHeight - 50);
}
stageWeb.loadURL(URL_ARRAY[url % 4]);
url++;
}
/**
*
* @param e
*/
private function tryGC(e:MouseEvent):void {
stageWeb.stage = null;
stageWeb.viewPort = null;
stageWeb.dispose();
stageWeb = null;
System.gc();
}
}
}
关于actionscript-3 - HTMLLoader/StageWebView 内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24642285/