2017-05-10 2 views
0

Mon jeu utilise environ 315 Mo de mémoire de base. Cependant, l'appel des fonctions suivantes entraîne une forte augmentation de l'utilisation de la mémoire, s'élevant à environ 480 Mo tout en atteignant des pics de 580 Mo et plus, accompagnés d'avertissements de mémoire et même de plantages. Que se passe-t-il? D'abord, le TakeScreenshot IEnum est appelé trois fois de suite, c'est-à-dire le nombre maxi de TakeScreenshotTakeScreenshotTakeScreenshotTakeScreenshot compte pour les captures d'écran en une session. Deuxièmement, la fonction SendEmailTask est appelée montrant les trois images pour l'utilisateur d'en choisir un. En choisissant l'image "# 1", la fonction SendImage1 est déclenchée.L'utilisation de la mémoire Unity iOS augmente et ne redescend plus

Peut-être que quelqu'un peut me montrer où et comment je peux récupérer une partie de cette mémoire, ce serait vraiment génial!

Tout code approprié devrait être ici:

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); 

    } 

} 

EDIT

profileur mémoire détaillée après être passé par la routine deux fois:

Detailed memory profiler after going thru the routine twice

Xcode mémoire profileur après être passé par la routine deux fois:

Xcode memory profiler after going thru the routine twice

+0

Avez-vous exécuté votre application avec le profileur en cours d'exécution? Cela vous permettra de voir exactement ce qui utilise tant de mémoire. – Eoghan

+0

Pouvez-vous télécharger une capture d'écran du profileur de mémoire détaillé après avoir utilisé votre application pendant un moment? Vous devez détruire chaque texture inutilisée ou elle restera en mémoire. –

+0

@JuanBayonaBeriso a édité ma question avec des captures d'écran. – somejonus

Répondre

0

À partir de votre rapport de profileur; Vous utilisez une grande partie de la mémoire sur les maillages et les éléments Texture2D, ce qui suggère que vous les dessinez/les cachez à l'utilisateur plutôt que de les supprimer de la mémoire. Plus de 50 Mo dans Texture2D Assets est un peu bizarre étant donné que vous avez encore plus de 120 Mo de Mailles. Je suppose que c'est un jeu en 3D, mais avec une interface 2D? Si oui, alors 50 Mo c'est beaucoup à dépenser sur les actifs de Texture2D. "Objets" sont ce que vous pensez qu'ils sont - ce sont des objets. Classes instanciées ou GameObjects contenant des composants attachés. Donc, si vous avez créé un objet Player GameObject et que vous y attachez un objet "playerStats" avec quelques variables de santé, de vitesse, d'endurance, etc., alors cela compterait comme 2 objets.

80 Mo n'est pas trop inquiétant pour les objets. Votre utilisation de Texture2D et Meshes est ce qui me semble être assez élevé pour un jeu qui cible iOS. Assurez-vous d'utiliser des modèles adaptés aux mobiles et des textures dont la résolution n'est pas trop élevée.

+0

Merci pour votre réponse! En reconsidérant mes maillages et textures, j'ai récupéré un cool de 60 Mo. Mais la mémoire continue d'ajouter beaucoup. Ce que j'ai découvert est la suivante: Lorsque 'SendEmailTask' est appelé, l'utilisation de la mémoire dans le profileur augmente de 150 Mo dont 54 Mo sont des objets et 96 Mo est Texture2Ds (les trois images - 32 Mo chacune) dans" Non enregistré " . Toutefois, lorsque SendImage1 est appelé et que tout est détruit, le profileur affiche uniquement une hausse de 7 Mo de 295 à 302 Mo pour l'ensemble de l'application. Xcode de l'autre côté est passé de 247 Mo à 372 Mo, ce qui est la nouvelle référence maintenant. – somejonus

+0

Ouais, alors c'est probablement ça? pouvez-vous réutiliser la mémoire de vos textures au lieu d'en créer de nouvelles? Je ne sais pas comment vous les chargez car vous utilisez un plugin d'actifs stan. –

0

J'ai eu un problème similaire avec les fichiers audio dans iOS, je ne sais pas si cela pourrait être votre cas.

J'ai chargé de gros fichiers audio de 20mb + sur la mémoire pour les traiter et ensuite libérer la mémoire, la chose est que la mémoire a continué à monter dans le profileur xcode. Ceci est dû à la fragmentation de la mémoire, vous pouvez en lire plus à ce sujet ici: https://stackoverflow.com/a/3770593/4024219

Ma solution était de charger les fichiers en petits morceaux et de réutiliser mes tableaux au lieu de créer et de détruire de nouveaux.

+0

Merci pour votre réponse! Pourriez-vous jeter un oeil à mon commentaire sur la réponse ci-dessous? On dirait que la fragmentation pourrait être mon problème aussi, depuis le chargement de ces trois 32 Mo Texture2Ds. Qu'est-ce que tu penses? – somejonus