我有a Flex 4.6 web game,它顯示2個帶有2個自定義項目渲染器的虛擬佈局的列表。渲染器主要由顯示用戶頭像和少量標籤的BitmapImages組成。在Flex 4.6 Web應用程序中找不到巨大的內存泄漏
的名單正在通過用gzip壓縮JSON數據TCP套接字經常更新。 I merge that data into 2 ArrayCollections充當列表的數據提供者。這似乎工作得很好,列表不閃爍並且正確更新(我已經監視了很多調試跟蹤信息)。
{
lobby: [
"OK252342810632",
"OK122471020773",
"DE54",
"DE6577",
"DE7981",
"OK225312168135",
"OK20629248715",
"DE7880",
],
games: [
{ 0: [] },
{ 9012: [
"VK48058967",
"MR14315189992643135976",
"OK10218913103",
] },
{ 9013: [
"OK305894249541",
"OK151358069597",
"OK515549948434",
] },
{ 9007: [
"OK366541092321",
"DE7062",
"OK122700338897",
] },
{ 8993: [
"OK78476527766",
"VK5692120"
] }
]
}
我的問題是,應用程序很快就會遲緩,對於一些用戶來說插件崩潰,所以用戶抱怨很多。
在我看到這幅畫的輪廓(跳轉到內存20 MB,並在那裏停留,有時跳轉到40MB等):
從探查我想不通 - 什麼是泄漏記憶。在頂部,我看到矢量。 < *>類別 - 無論如何。
我試過這麼多的事情已經解決這個問題:
從本地JSON.parse()來回到com.brokenfunction.json.decodeJson()(因爲我想,也許得到的Adobe交換這是錯誤的)
- 我刪除了JSON對象,我分析後:
私有函數handleTcpData(事件:ProgressEvent):無效{ //讀取ByteArray的插座上,將它解壓縮 - 行之有效
var obj:Object = decodeJson(_bytes.toString()); // merge into 2 ArrayCollections, update GUI... works well? for (var key:String in obj) delete obj[key]; obj = null;
}
我已經關掉ContentCache關閉 - 沒有什麼區別
我使用任何臨時停止。對象,如{ID: 「DE22」},並使用JSON對象直接
是否有人請有好的建議?
我讀過很多關於AS3垃圾收集和常用技巧的文檔/博客:將對象引用設置爲null,使用弱事件偵聽器,removeChild()不釋放內存等 - 但我沒有看看如何將這個應用到我的問題。
以下是我的完整大堂。MXML源代碼:
<?xml version="1.0" encoding="utf-8"?>
<s:Group
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:comps="*"
width="700" height="450">
<fx:Declarations>
<s:RadioButtonGroup id="_filter" change="handleRadio(event);" />
</fx:Declarations>
<fx:Metadata>
[Event(name="game", type="PrefEvent")]
</fx:Metadata>
<fx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import mx.utils.ObjectUtil;
[Bindable]
private var _games:ArrayCollection = new ArrayCollection();
[Bindable]
private var _users:ArrayCollection = new ArrayCollection();
private function handleRadio(event:Event):void {
switch (_filter.selection) {
case _allBtn:
_games.filterFunction = null;
break;
case _vacBtn:
_games.filterFunction = vacantGame;
break;
case _fullBtn:
_games.filterFunction = fullGame;
break;
}
_games.refresh();
}
private function vacantGame(obj:Object):Boolean {
for (var id:String in obj) {
var players:Array = obj[id];
return players.length < 3;
}
return false;
}
private function fullGame(obj:Object):Boolean {
for (var id:String in obj) {
var players:Array = obj[id];
return players.length == 3;
}
return false;
}
// merge arrays of objects
private function mergeObjs(ac:ArrayCollection, array:Array):void {
var i:int;
var j:int;
var n:int;
var src:Array = ac.source;
// 1) remove items missing in data from _data
FOUND1:
for (i = src.length - 1; i >= 0; i--) {
for (j = array.length - 1; j >= 0; j--) {
if (ObjectUtil.compare(src[i], array[j]) == 0)
continue FOUND1;
}
n = ac.getItemIndex(src[i]);
if (Util.DEBUG)
trace('REMOVED OBJ ' + src[i] + ' filtered n=' + n + ' i=' + i);
// remove visible items
if (n > -1)
ac.removeItemAt(n);
// remove hidden (filtered) items
else
src.splice(i, 1);
}
// 3) add items appeared in data to _data
FOUND2:
for (j = 0; j < array.length; j++) {
for (i = 0; i < src.length; i++) {
if (ObjectUtil.compare(src[i], array[j]) == 0)
continue FOUND2;
}
if (Util.DEBUG)
trace('ADDED OBJ ' + array[j] + ' i=' + i);
//ac.addItemAt(array[j], i);
ac.addItem(array[j]);
}
}
// merge arrays of strings (the user ids)
private function mergeIds(ac:ArrayCollection, array:Array):void {
var i:int;
var j:int;
var n:int;
var src:Array = ac.source;
// 1) remove items missing in data from _data
FOUND1:
for (i = src.length - 1; i >= 0; i--) {
for (j = array.length - 1; j >= 0; j--) {
if (i == j)
continue FOUND1;
}
n = ac.getItemIndex(src[i]);
if (Util.DEBUG)
trace('REMOVED ID ' + src[i] + ' filtered n=' + n + ' i=' + i);
// remove visible items
if (n > -1)
ac.removeItemAt(n);
// remove hidden (filtered) items
else
src.splice(i, 1);
}
// 3) add items appeared in data to _data
FOUND2:
for (j = 0; j < array.length; j++) {
for (i = 0; i < src.length; i++) {
if (i == j)
continue FOUND2;
}
if (Util.DEBUG)
trace('ADDED ID ' + array[j] + ' i=' + i);
ac.addItem(array[j]);
}
}
public function update(games:Array, lobby:Array):void {
var vac:uint = 0;
var full:uint = 0;
for each (var game:Object in games) {
for (var id:String in game) {
var players:Array = game[id];
if (!players)
continue;
if (players.length < 3)
vac++;
else if (players.length == 3)
full++;
}
}
if (games)
mergeObjs(_games, games);
if (lobby)
mergeIds(_users, lobby);
_allBtn.label = 'All ' + _games.source.length;
_vacBtn.label = 'Vacant ' + vac;
_fullBtn.label = 'Full ' + full;
}
public function appendText(str:String):void {
_chat.appendText(str);
}
]]>
</fx:Script>
<s:VGroup width="100%" height="100%">
<s:HGroup width="100%" verticalAlign="baseline" paddingLeft="8" paddingRight="8">
<s:Label text="Игровые столы:" />
<s:RadioButton id="_allBtn" group="{_filter}" label="Все" selected="true" />
<s:RadioButton id="_vacBtn" group="{_filter}" label="Свободные" />
<s:RadioButton id="_fullBtn" group="{_filter}" label="Полные" />
<s:Spacer width="100%" />
<s:Label text="Игроки в лобби: {_users.length}" />
</s:HGroup>
<mx:HDividedBox width="100%" height="100%">
<s:List id="_gamesList" itemRenderer="Game" useVirtualLayout="true" dataProvider="{_games}" skinClass="PrefListSkin" width="100%" height="100%" minWidth="180">
<s:layout>
<s:TileLayout />
</s:layout>
</s:List>
<mx:VDividedBox width="180" height="100%" minWidth="180">
<s:List id="_usersList" itemRenderer="User" useVirtualLayout="true" dataProvider="{_users}" skinClass="PrefListSkin" width="100%" height="100%" minHeight="150">
<s:layout>
<s:TileLayout />
</s:layout>
</s:List>
<s:TextArea id="_chat" width="100%" height="100%" minHeight="40" editable="false" fontSize="14" color="#000000" horizontalScrollPolicy="off"/>
</mx:VDividedBox>
</mx:HDividedBox>
</s:VGroup>
</s:Group>
UPDATE:
我必須補充一點,我從XML轉換成JSON後,我的問題(用戶抱怨可再現的Flash插件崩潰)已經開始。
我已經重新運行探查和爲什麼它顯示JSON.parseCore 987個實例,同時也有400只在大堂用戶(只有極少數目前正在與虛擬佈局的列表可見)?
任何想法請,當我從XML去JSON什麼可能有哪些變化? (我沒有碰別人)。我實際上希望獲得更好的性能,因爲我有時會閱讀有關Flex中XML泄漏內存的問題...
在這一點上,我會嘗試兩件事情。 1消除/減少,即一次刪除應用程序的塊,並根據扣除情況查看導致內存泄漏的操作。 2創建或使用現有的記錄器類,記錄每個函數開始和結束時的執行時間和日誌消息,並輸出總內存。 http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/system/System.html#totalMemory – shaunhusain 2012-03-16 16:52:32
在這裏查看util包,我發佈了一個記錄器,它可以完成我在上面解釋的http:// www.shaunhusain.com/DrawTextRandomly/srcview/ – shaunhusain 2012-03-16 16:52:53
也作爲cupuyc表示,這似乎不是一個內存泄漏給我,我期望在剖析器中看到一致的上升線,如果它,而是我只看到尖峯當一些東西被加載,然後一條扁平線表示內存是穩定的。 – shaunhusain 2012-03-16 17:00:04