2010-06-01 5 views
1

플래시 앱에서 메모리 관리에 문제가 있습니다. 메모리 사용량은 상당히 증가하고 자산을로드하는 방식까지 추적했습니다.플래시/플렉스/AS3에서의 메모리 사용

내가 그때 인스턴스 자산이 방법이 시점에서

var pClass : Class = Embedded[sResource] as Class; 
return new pClass() as Bitmap; 

을이

[Embed(source="/home/gabriel/text_hard.jpg")] 
public static var ASSET_text_hard_DOT_jpg : Class; 

같은 내장 클래스에 여러 래스터 이미지를 포함, 메모리 사용량은 완벽하게 정상이다, 상승 . 그러나 null 개체에 대한 모든 참조를 메모리를 해제하지 않습니다.

플래시 플레이어가 처음 요청할 때 플래시 플레이어가 클래스의 인스턴스를 만드는 것처럼 보이지만 절대로 릴리스하지 않습니다. 참조없이 System.gc()를 호출하고 Double LocalConnection 트릭을 수행합니다. 또는 BitmapData 객체에서 dispose()를 호출해야합니다.

물론 이것은 매우 바람직하지 않습니다. 오래 전에 자산을 일부 사용하지 않았는지 여부에 관계없이 SWF의 모든 것이 인스턴스화 될 때까지 메모리 사용량이 늘어날 것입니다.

내 분석이 맞습니까? 이 문제를 해결하기 위해 무엇인가 할 수 있습니까?

답변

0

언로드되지 않은 개체에 대한 참조를 유지하는 것으로 나타났습니다. 아주 까다 롭습니다. GC는 필자가 설명한 모든 경우에 올바르게 작동합니다.

SWF를로드하고 정의 된 많은 클래스를 인스턴스화 한 다음 표시 목록에 추가하고 조작 한 다음 모든 참조를 제거하고 SWF를 언로드하면 거의 동일한 메모리로 시작됩니다.

0

왜 이것을 사용 하시겠습니까 ???

var pClass : Class = Embedded[sResource] as Class; 
return new pClass() as Bitmap; 

가끔 동적 자원 할당이 버그가있어서 해제되지 않습니다. 플래시 플레이어와 플렉스를 사용하기 전에 비슷한 문제가있었습니다. 로드 및 언로드 같은 외부 swf ... 내가 system.gc() 호출하는 경우에도 추락하지 않고 메모리로드 된 swf 크기를 지속적으로 증가했다; swf를 언로드 한 후

제 제안은이 접근법을 건너 뛰고 설명한 첫 번째 사례를 사용하는 것입니다.


UPDATE 1

<?xml version="1.0" encoding="utf-8"?> 
<s:Application 
    xmlns:fx   = "http://ns.adobe.com/mxml/2009" 
    xmlns:s   = "library://ns.adobe.com/flex/spark" 
    xmlns:mx   = "library://ns.adobe.com/flex/mx" 
    creationComplete = "creationComplete()"> 

<fx:Script> 
    <![CDATA[ 



     [Embed(source="/assets/logo1w.png")] 
     private static var asset1:Class; 

     [Embed(source="/assets/060110sinkhole.jpg")] 
     private static var asset2:Class; 


     private static var _dict:Dictionary = new Dictionary(); 

     private static function initDictionary():void 
     { 
      _dict["/assets/logo1w.png"] = asset1; 
      _dict["/assets/060110sinkhole.jpg"] = asset2; 
     } 

     public static function getAssetClass(assetPath:String):Class 
     { 
      // if the asset is already in the dictionary then just return it 
      if(_dict[assetPath] != null) 
      { 
       return _dict[assetPath] as Class; 
      } 

      return null; 
     } 

     private function creationComplete():void 
     { 
      initDictionary(); 
      var asset1:Class = getAssetClass("/assets/logo1w.png"); 
      var asset2:Class = getAssetClass("/assets/060110sinkhole.jpg"); 
      var asset3:Class = getAssetClass("/assets/logo1w.png"); 
      var asset4:Class = getAssetClass("/assets/060110sinkhole.jpg"); 
      var asset5:Class = getAssetClass("/assets/logo1w.png"); 
     } 
    ]]> 
</fx:Script> 

+1

죄송합니다. 따라 가기가 어렵습니다. 나는 그것을하는 한 가지 방법만을 설명했다. 첫 번째 스 니펫은 애셋을 포함하는 방법과 내가 인스턴스화하는 방법을 보여줍니다. 왜 그냥'새로운 ASSET_text_hard_DOT_jpg()'를하지 않는 것입니까? 그 이유는 내 코드가 복잡하기 때문에 미리 필요한 부분을 미리 알 필요가 없기 때문입니다. 예를 들어 여러 조각으로 된 문자열을 만들어 이름이 지정된 이미지 (예 : "text_"+ s_lDifficulty [nDifficulty] -> "text_hard")를 얻습니다. – ggambett

+0

미안하지만 당신이 성취하려고하는 것은 불가능하다고 생각합니다. swf가 빌드 될 때 리소스가 임베디드 된 것을 알기 때문에 설명한대로 리소스를 동적으로 포함 할 수 있는지 확신하지 못합니다. 사전을 만들고 필요한 모든 리소스를 배치하려면 어떻게해야합니까? 나는 그것을 응답에서 지금 작성한 UPDATE1 코드와 같이 사용할 것입니다. –

1

당신이 아닌 디버그 플레이어에서 다시 테스트를 실행합니다. 디버그 플레이어가 자산을 공개 할 때 항상 모든 메모리를 올바르게 회수하지는 않습니다.

또한로드 된 애셋이 아닌 임베디드 애셋을 사용하고 있기 때문에 실제 데이터가 공개되지 않을 수도 있습니다. SWF의 일부이기 때문에 SWF 수명 동안 메모리에있을 것으로 합리적으로 기대할 수 있습니다.

0

이 시점에서 메모리 사용은 정상적으로 정상적으로 올라갑니다 ( ). 그러나 개체에 대한 모든 참조를 null로 설정해도 메모리가 해제되지는 않습니다.

이는 또한 정상적으로 처리됩니다. 모든 시스템에서 코드에서 객체 참조를 중지하는 순간이 메모리의 메모리가 운영 체제로 반환되는 것과 동일한 순간을 보장하는 경우는 거의 없습니다. 이것이 System.gc()와 같은 메소드가 필요한 이유입니다. 필요할 때 클린업 할 수 있습니다. 일반적으로 응용 프로그램은 효율적인 용도로 객체 및 메모리를 유지하기 위해 일종의 풀링을 구현할 수 있습니다 (메모리 할당이 일반적으로 느리기 때문에).응용 프로그램이 메모리를 운영 체제로 반환하더라도 OS는 잠시 후에 응용 프로그램에 할당 된 것으로 간주 할 수 있습니다.

해제 된 메모리가 다시 사용되지 않는지 걱정하면됩니다. 예를 들어, 객체를 만들고 자유롭게하고이 과정을 반복하면 이전에 해제 된 객체의 메모리가 새 객체에 다시 할당되므로 메모리 사용이 생성 된 객체 수에 따라 선형 적으로 증가하지 않아야합니다. 그것이 발생하지 않는다고 확신 할 수 있다면 질문을 편집하여 그렇게 말하십시오. :)