Search Unity

texture.LoadImage(bytes) memory leak

Discussion in 'Editor & General Support' started by Plow-Digital, Feb 5, 2016.

  1. Plow-Digital

    Plow-Digital

    Joined:
    Mar 5, 2014
    Posts:
    6
    Hi everyone,

    I'm having an issue clearing memory after using texture.LoadImage(bytes). I have tried many different ways to clear the memory, but have come up empty. Below is a sample script that shows the issue. The List<string> images is just a list of urls. Line 55 (texture.LoadImage(bytes)) is where the problem happens. Thank you for any help!

    using UnityEngine;
    using System.Collections;

    using System.Collections.Generic;
    using System.IO;

    public class Sample:MonoBehaviour {

    private TextMesh textMesh = null;
    private int count = 0;

    public void Awake() {
    textMesh = gameObject.GetComponent<TextMesh>();

    StartCoroutine(Download());
    }

    public IEnumerator Download() {
    textMesh.text = "Initializing download...";

    yield return new WaitForSeconds(5); // to give unity time to finish initializing to stabilize start-up memory

    List<string> images = Data.GetImages();

    for (int i = 0; i < images.Count; i++) {
    textMesh.text = "Downloading " + (i + 1) + " out of " + images.Count + " images.";
    yield return StartCoroutine(DownloadFromUrl(images));
    count ++;
    }

    images.Clear();
    images = null;

    textMesh.text = "Download complete!";

    yield break;
    }

    public IEnumerator DownloadFromUrl(string url) {
    byte[] bytes = null;

    WWW www = new WWW(url);

    yield return www;

    if (string.IsNullOrEmpty(www.error) && www.bytes != null)
    bytes = www.bytes;

    www.Dispose();
    www = null;

    if (bytes != null) {
    Texture2D texture = new Texture2D(4096, 4096, TextureFormat.ARGB32, false);

    texture.LoadImage(bytes); // THIS IS THE PROBLEM LINE

    bytes = texture.EncodeToPNG();

    CreateFileInData(count + ".png", bytes);

    if (texture != null) {
    DestroyImmediate(texture, true);
    texture = null;
    }

    bytes = null;

    yield return Resources.UnloadUnusedAssets();
    System.GC.Collect();
    }

    yield break;
    }

    public static void CreateFileInData(string localUrl, byte[] bytes) {
    string url = Path.Combine(Application.persistentDataPath, localUrl);

    string directory = Application.persistentDataPath;
    localUrl = localUrl.Replace("\\", "/");
    string[] localUrlArray = localUrl.Split("/"[0]);
    for (int i = 0; i < localUrlArray.Length - 1; i++) {
    directory += "/";
    directory += localUrlArray;
    }

    if (!Directory.Exists(directory))
    Directory.CreateDirectory(directory);

    FileStream file = File.Create(url);
    file.Write(bytes, 0, bytes.Length);
    file.Close();

    #if !UNITY_EDITOR && UNITY_IPHONE
    iPhone.SetNoBackupFlag(url);
    #endif
    }
    }
     
  2. liortal

    liortal

    Joined:
    Oct 17, 2012
    Posts:
    3,562
    How do you know you're leaking? can you share a profiler screenshot to see you're actually leaking memory?
     
  3. Plow-Digital

    Plow-Digital

    Joined:
    Mar 5, 2014
    Posts:
    6
    Below are before and after screenshots of my task manager. The problem does not seem to show up in the Unity Editor Profiler, but the exe does build up memory and the real exe (not the sample code above) eventually crashes from this issue. If I don't run texture.LoadBytes, no memory builds up.

    Before:
    upload_2016-2-11_15-22-20.png

    After:
    upload_2016-2-11_15-23-19.png
     

    Attached Files:

  4. liortal

    liortal

    Joined:
    Oct 17, 2012
    Posts:
    3,562
    I dont think looking at the editor's memory usage is any indication to memory leaks in your game... you should profile the game itself.
     
  5. Plow-Digital

    Plow-Digital

    Joined:
    Mar 5, 2014
    Posts:
    6
    That's part of the problem. The Unity Profiler is not showing the memory leak. It says that texture memory is perfectly fine. When I look at the Windows Process Explorer, viewing either the Unity Editor or an exported exe, it says that the memory is increasing. If I use texture.LoadBytes(), the Process Explorer shows the memory climbing. If I do not use texture.LoadBytes(), the memory does not climb. With or without texture.LoadBytes(), the bytes are already loaded in using WWW in my code, and not causing the leak on their own. but I need those bytes to become a texture. I can load textures from Resources.Load and clear those out of memory, but I need to be able to load textures from outside the project.

    Also, thank you for the replies.
     
  6. nbalexis1

    nbalexis1

    Joined:
    Jul 21, 2011
    Posts:
    89
    antonsem likes this.