8

나는 1 개의 부모 액티비티를 가진 복잡한 배틀 시스템을 가지고 있으며 배틀을 확장하고 해당 컨텍스트를 해당 클래스에 전달함으로써 BattleActivity의 정적 변수에 액세스하는 여러 하위 클래스를가집니다.안드로이드 - 할당 된 메모리 해제 AnimationDrawable 사용 중

이 모든 것이 정상적으로 작동하는 것 같습니다. 그러나 모든 AnimationDrawables를 메모리에서 해제하는 데 문제가 있습니다. 전투 중에 총 24 개의 DrawableAnimations가 사용될 수 있습니다. 이제는 괜찮습니다. 그러나 사용자가 새로운 괴물을 만날 때마다 4 개의 AnimationDrawables가 메모리에 추가됩니다. 메모리에 천천히 그러나 서두름으로 인해 내 앱이 부족 메모리 부족 예외로 인해 중단됩니다.

따라서 전투 시스템이 종료되는 즉시 모든 메모리를 해제 할 수있는 방법을 찾아야합니다. 현재 Sony Z2에서 테스트 중이며 사용자가 전투에 참가하면 mmmory가 91MB에서 230MB로 증가합니다. 전투가 끝나면이 메모리 사용량을 다시 91MB로 낮춰야합니다. 아주 기본적인 코드 스 니펫을 추가하여 현재 앱의 흐름과 메모리를 해제하기 위해 무엇을 하려는지 아이디어를 제공합니다.

public class Battle extends Activity 
{ 
    // I have several AnimationDrawables loaded into memory 
    // These are then assigned the relevent animation to a button swicthing between these animations throughout my battle 
    ImageButton btnChr1; 
    AnimationDrawable cAnimHit1; 
} 

//This is the use of one of those AnimationDrawables 
public class Battle_Chr_Anim extends Battle 
{ 
    protected Context ctx; 
    private ImageButton btnChr1; 
    AnimationDrawable cAnimHit1; 

    public Battle_Chr_Anim(Context c, ImageButton _btnChr1, AnimationDrawable _cAnimHit1) { 
     this.ctx = c; 
     this.btnChr1 = _btnChr1; 
     this.cAnimHit1 = _cAnimHit1; 
    } 

    // Bound the ImageButton 
    int id = ctx.getResources().getIdentifier("idle", "drawable", ctx.getPackageName()); 
    img_chr1.setBackgroundResource(id); 
    frameAnimation = (AnimationDrawable)img_chr1.getBackground(); 
    frameAnimation.start() 

    // Loaded into memory ready so I can swicth them over quickly when user attacks 
    int ca1 = ctx.getResources().getIdentifier("attack", "drawable", ctx.getPackageName()); 
    cAnimHit1 = (AnimationDrawable)chrHit1.getBackground(); 
    cAnimHit1.start(); 
} 

public class Battle_Ended extends Battle 
{ 
    protected Context ctx; 

    public Battle_Ended(Context c) { 
     this.ctx = c; 
    } 

    //This is a dialog popup when the user completes the battle closing the battle activty 
    void EndBattle() 
    { 
     ImageButton btnSubmit = (ImageButton)dialog.findViewById(R.id.imgBtnSubmit); 
     btnSubmit.setOnClickListener(new OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       Intent returnIntent = new Intent(); 
       setResult(RESULT_CANCELED, returnIntent); 
       RecyleAllAnimations(); 
       dialog.dismiss(); 
       ((Activity) ctx).finish(); 
      } 
     }); 
    } 

    void RecyleAllAnimations() 
    { 
     // I want all AnimationDrawables from memory here, I believe the below line removes the one currently in use, however I have no way of releasing the other animations sitting in memory. 
     img_chr1.setBackgroundResource(android.R.color.transparent); 
     System.gc(); 
    } 
} 
+0

응용 프로그램 컨텍스트를 전달하는 정적 변수가 실제로 있습니까? 나는 당신이 당신의 드로어보다 훨씬 빨리 앱을 죽일 것이라고 생각한다. – TheRedFox

+0

네, 이것은 내 Activity의 모든 코드를 원하지 않고 단순히이 클래스를 확장하여 여전히 UI.사용자가 전투에 들어갈 때 애니메이션이 유창 할 수 있도록 Activity를로드하기 전에 모든 AnimationDrawables를로드 할 수 있어야합니다. –

답변

0

는 무엇보다도 나는 당신이이 선언되는 범위를 떠나지 않는 한 AnimationDrawable에 대한 재활용을 할 수 있다고 생각합니다. System.gc();에서 중계하지 말고 GC가 자동으로 해당 메모리를 해제하도록하십시오. BattleActivity

의 정적 변수에 액세스

이 첫 번째 실수입니다. 활동을 떠나도 정적 변수를 사용하면 모든 변수가 그대로 유지되고 OOM을 얻게됩니다.

따라서, 퇴장하자마자 내 전투 시스템이 모든 메모리를 해제 할 수있는 방법을 찾아야합니다.

모든 변수를 비 정적 변수로 선언하면 정의 된 범위를 벗어날 때 OOM을 얻지 못할 것입니다. AnimationDrawable을 만들면 활동이 진행되는 동안 아무런 경계도없이 OOM을 얻을 수 있습니다.

+0

정적 코드를 수정하여 더 이상 정적 AnimationDrawable을 사용하지 않지만 여전히 사용 가능합니다. 활동이 파괴되고 사용자가 Game Map 페이지로 돌아온 후에도 메모리를 해제하는 문제가 있습니다. 다른 아이디어? –

+0

지금 어떤 문제가 있습니까? – mmlooloo

+0

음 간단히 말해서 메모리가 AnimatonDrawables 용으로 출시되지 않고 있습니다. –

0

드로어 블이 상태를 유지하기 때문에 정적 드로잉 또는 뷰를 사용하면 메모리 누수가 발생합니다.

당신도 다른 정적 드로어 블 (들) 또는보기 (들)를 확인하고 그들을 제거 또는

drawable.setCallback(null); 

당신은 드로어 블 오브젝트를 재활용 할 수 없습니다 호출이 시스템을 호출하는 것은 좋은 방법이 아닙니다 수 .gc()

위의 코드를 시도해 본 결과 메모리가 계속 확장되는 경우 memory analysis을 사용하여 문제의 범위를 좁히는 것이 좋습니다.

+0

나는 메모리 누출로 고통 받고 있다는 사실은 생각하지 않는다. 나는 메모리의 깎아 지른 양을 drawable이 사용한다고 생각한다. 한 번의로드에서 30 개의 AnimationDrawable을로드해야한다는 것을 의미합니다. 각각의 애니메이션은 256px x 256px의 대략 15 개의 이미지로 구성됩니다. 따라서 예상대로 메모리 사용량이 증가합니다 (장치 기반으로로드하는 데 2-4 초 소요). 이것은 내가 처리 할 수 ​​있지만 이것들은 내가 어떻게 든 그 메모리를 공개 할 필요가있다. 새로운 몬스터가 나올 때마다 추가로 5 개의 AnimationDrawables가 메모리에 추가됩니다. –

+0

사실입니다.하지만 액티비티가 유출되지 않은 경우 Activity를 닫은 후에 System.gc()를 수동으로 호출 한 경우에도 필요에 따라 메모리를 릴리스해야합니다. 누출이없는 한 메모리를 정리해야합니다. 정적 Drawable (s)를 사용하는 것과 옆에있는 경우 내가 언급 한 다른 것들이 가능한 Lootering을 피하기 위해 끝날 때 null을 가리킨다 –

+0

나는 모든 ImageViews에서 정적을 제거해야 할 필요가 있음을 고려해야 할 것이라고 생각합니다. 그런 다음 ImageButton이 제대로 테스트 할 수 있습니다. 메모리 누수 및 메모리 분석 도구를 확인하는 가장 좋은 방법은 무엇입니까? –