2017-05-10 17 views
0

내 게임의 기본 메모리 사용량은 약 315MB입니다. 그러나 다음 함수를 호출하면 메모리 사용량이 급격히 증가하고 약 480MB로 평준화되며 580MB 이상의 스파이크에 도달하면 메모리 경고 및 충돌이 발생합니다.Unity iOS 메모리 사용량이 증가하고 다시 돌아 가지 않음

어떻게됩니까? 먼저 TakeScreenshot IEnum이 최대 세 번 연속해서 호출됩니다. 한 세션의 스크린 샷 수입니다. 둘째로, 사용자가 하나를 선택할 수 있도록 세 개의 그림을 모두 표시하는 함수 SendEmailTask이 호출됩니다. 그림 "# 1"을 선택하면 기능 SendImage1이 트리거됩니다.

어쩌면 누군가가 그 기억의 일부를 어디서 어떻게 얻을 수 있는지 가르쳐 줄 수 있습니다. 그러면 정말 좋을 것입니다!

모든 관련 코드는 여기에 있어야한다 :

public class Picture : MonoBehaviour { 

    private int ssCount = 0; 

    private Sprite cachedImage1sprite; 
    private Sprite cachedImage2sprite; 
    private Sprite cachedImage3sprite; 

    private Texture2D cachedImage1; 
    private Texture2D cachedImage2; 
    private Texture2D cachedImage3; 

    private Texture2D JPGtex1; 
    private Texture2D JPGtex2; 
    private Texture2D JPGtex3; 

    private Texture2D tex; 


    void Awake() { 


    } 

    // Use this for initialization 
    void Start() { 

     JPGtex1 = new Texture2D (2, 2, TextureFormat.RGB24, false); 
     JPGtex2 = new Texture2D (2, 2, TextureFormat.RGB24, false); 
     JPGtex3 = new Texture2D (2, 2, TextureFormat.RGB24, false); 

     // Create a texture the size of the screen, RGB24 format 
     int width = Screen.width; 
     int height = Screen.height; 
     tex = new Texture2D(width, height, TextureFormat.RGB24, false); 


    } 

    // Update is called once per frame 
    void Update() { 

     if (ssCount == 0) { 

      SendEmail.interactable = false; 
      TakePhoto.interactable = true; 

     } else if (ssCount == 1) { 

      SendEmail.interactable = true; 

     } else if (ssCount == 3) { 

      TakePhoto.interactable = false; 

     } 

     //Debug.Log (ssCount); 

    } 


    void SendEmailTask(){ 

     if (ssCount == 3) { 

      cachedImage1 = SA.IOSNative.Storage.AppCache.GetTexture ("IMAGE_1"); 

      cachedImage2 = SA.IOSNative.Storage.AppCache.GetTexture ("IMAGE_2"); 

      cachedImage3 = SA.IOSNative.Storage.AppCache.GetTexture ("IMAGE_3"); 

      ImagePicker.SetActive (true); 

      //Image1 
      Rect rec1 = new Rect(0, 0, cachedImage1.width, cachedImage1.height); 
      cachedImage1sprite = Sprite.Create(cachedImage1, rec1, new Vector2(0,0),1); 
      Image1.image.sprite = cachedImage1sprite; 

      //Image2 
      Rect rec2 = new Rect(0, 0, cachedImage2.width, cachedImage2.height); 
      cachedImage2sprite = Sprite.Create(cachedImage2, rec2, new Vector2(0,0),1); 
      Image2.image.sprite = cachedImage2sprite; 

      //Image3 
      Rect rec3 = new Rect(0, 0, cachedImage3.width, cachedImage3.height); 
      cachedImage3sprite = Sprite.Create(cachedImage3, rec3, new Vector2(0,0),1); 
      Image3.image.sprite = cachedImage3sprite; 

      SA.IOSNative.Storage.AppCache.Remove ("IMAGE_1"); 
      SA.IOSNative.Storage.AppCache.Remove ("IMAGE_2"); 
      SA.IOSNative.Storage.AppCache.Remove ("IMAGE_3"); 

     } 

    } 

    IEnumerator TakeScreenshot() { 

     // Wait till the last possible moment before screen rendering to hide the UI 
     yield return null; 
     GameObject.Find("Buttons").GetComponent<Canvas>().enabled = false; 
     FlashImage(); 

     // Wait for screen rendering to complete 
     yield return new WaitForEndOfFrame(); 

     // Create a texture the size of the screen, RGB24 format 
     int width = Screen.width; 
     int height = Screen.height; 

     // Read screen contents into the texture 
     tex.ReadPixels(new Rect(0, 0, width, height), 0, 0); 
     tex.Apply(); 

     //byte[] screenshot = tex.EncodeToPNG(); 

     print("Size is " + tex.width + " by " + tex.height); 

     if (ssCount == 0) { 

      SA.IOSNative.Storage.AppCache.Save ("IMAGE_1", tex); 

      ssCount++; 

     } else if (ssCount == 1) { 

      SA.IOSNative.Storage.AppCache.Save ("IMAGE_2", tex); 

      ssCount++; 

     } else if (ssCount == 2) { 

      SA.IOSNative.Storage.AppCache.Save ("IMAGE_3", tex); 

      ssCount++; 

     } 

     IOSCamera.Instance.SaveTextureToCameraRoll(tex); //Save to Cameraroll 

     // Show UI after we're done 
     GameObject.Find("Buttons").GetComponent<Canvas>().enabled = true; 

    } 


    public void SendImage1() { 

     byte[] screenshot1; 

     screenshot1 = cachedImage1.EncodeToJPG(); 

     if (Facebook == false) { 

      JPGtex1.LoadImage (screenshot1); 

      TextureScale.Bilinear (JPGtex1, 1200, 900); 

      IOSSocialManager.Instance.SendMail (SubjectText, EmailText, "", JPGtex1); 

     } else { 

      StartCoroutine(UploadToPage(screenshot1)); 

     } 

     backToGame(); 

    } 

    public void backToGame() { 

     Destroy (cachedImage1sprite); 
     Destroy (cachedImage2sprite); 
     Destroy (cachedImage3sprite); 

     SA.IOSNative.Storage.AppCache.Remove ("IMAGE_1"); 
     SA.IOSNative.Storage.AppCache.Remove ("IMAGE_2"); 
     SA.IOSNative.Storage.AppCache.Remove ("IMAGE_3"); 

     Destroy(cachedImage1); 
     Destroy(cachedImage2); 
     Destroy(cachedImage3); 

     cachedImage1 = null; 
     cachedImage2 = null; 
     cachedImage3 = null; 

     Image3Obj.SetActive (true); 

     ImagePicker.SetActive (false); 

    } 

} 

편집

자세한 메모리 프로파일 두 번 루틴을 통해 진행 후 :를 통해 진행 한 후

Detailed memory profiler after going thru the routine twice

엑스 코드 메모리 프로파일 루틴 두 번 :

Xcode memory profiler after going thru the routine twice

+0

프로파일 러를 실행하여 응용 프로그램을 실행 했습니까? 이렇게하면 많은 양의 메모리를 사용하는 것을 정확히 볼 수 있습니다. – Eoghan

+0

잠시 동안 앱을 사용한 후에 자세한 메모리 프로파일 러의 스크린 샷을 업로드 할 수 있습니까? 사용하지 않는 모든 텍스처를 파괴해야합니다. 그렇지 않으면 메모리에 남아 있습니다. –

+0

@JuanBayonaBeriso가 스크린 샷으로 내 질문을 편집했습니다. – somejonus

답변

0

프로필러 보고서에서;

Meshes와 Texture2D Assets에 많은 양의 메모리를 사용하고 있습니다. 메모리에서 실제로 제거하지 않고 사용자를 그릴 수 있거나 숨길 수 있다고 생각합니다. Texture2D Assets의 50MB 이상은 120MB 이상의 메쉬가로드되어 있다고 생각하면 좀 이상합니다. 3D 게임이지만 2D UI가 있다고 가정합니다. 그렇다면 50MB는 Texture2D Assets에 많은 돈을 쓰는 것입니다.

"개체"는 개체라고 생각하는 개체입니다. 개체입니다. 인스턴스화 된 클래스 또는 첨부 된 구성 요소가 포함 된 GameObjects. Player GameObject를 만든 경우, 그 속성은 건강, 속도, 체력 등에 대한 몇 가지 변수가있는 "playerStats"객체입니다. 그러면 그 객체는 2 개의 객체로 계산됩니다.

80MB는 객체를 너무 걱정하지 않습니다. Texture2D와 Mesh는 iOS를 목표로하는 게임에서 꽤 인상적이었던 것을 사용합니다. 모바일 친화적 인 모델과 해상도가 지나치게 높지 않은 텍스처를 사용하고 있는지 확인하십시오.

+0

답변 해 주셔서 감사합니다! 내 메쉬와 텍스처를 재검토하면 멋진 60 MB가 다시 생겼습니다. 그러나 그 추억은 아직도 많이 늘어나고 있습니다. 'SendEmailTask'가 호출되면 프로파일 러의 메모리 사용량은 150 MB만큼 증가합니다. 54 MB는 Objects이고 96 MB는 Texture2D입니다 (3 개의 이미지 - 각각 32 MB). "Not Saved" . 그러나'SendImage1'이 호출되고 모두 파괴되면 프로파일 러는 전체 앱에 대해 295MB에서 302MB까지 7MB 하이킹 만 표시합니다. 다른 쪽의 Xcode는 247MB에서 372MB로 변경되었습니다. 현재 새로운 기준이되었습니다. – somejonus

+0

그래, 그게 아마도 그거야? 새로운 텍스처를 만드는 대신 텍스처의 메모리를 재사용 할 수 있습니까? 스탠 자산의 플러그인을 사용하면서 어떻게로드하고 있는지 모르겠습니다. –

0

나는 iOS에서 오디오 파일과 비슷한 문제가 있었지만, 이것이 귀하의 경우인지는 모르겠다.

20MB 이상의 큰 오디오 파일을 메모리에로드하여 처리 한 다음 메모리를 릴리스하면 xcode 프로파일 러에서 메모리가 계속 올라 가게됩니다. 이것은 메모리 단편화로 인해 발생합니다. 여기에 대한 자세한 내용은 https://stackoverflow.com/a/3770593/4024219

작은 파일로로드하고 새 배열을 만들고 파괴하는 대신에 파일을로드하는 것이 해결책이었습니다.

+0

답변 해 주셔서 감사합니다. 아래 답변에 대한 내 의견을 살펴볼 수 있습니까? 3 개의 32 MB Texture2D를로드 한 이후로 조각화가 내 문제 일 수도 있습니다. 어떻게 생각해? – somejonus