로드된 텍스쳐 메모리 관리


MemoryTest.zip










동적으로 로드된 Texture2D 는 소거 할때 잘 지워 줘야 메모리에 쌓이지 않는다. 


실제로 1024 x 1024 텍스쳐 하다당 약 6 메가에 육박하는 메모리가 올라가기 때문이다. 


테스트는 임의의 텍스쳐(1024 x 1024)를 만들고 이것을 여러가지 방법으로 적용 한 다음 소멸 시켜 보는것이다.







Test1 : 단순 Texture2D 를 로드 하여 List<Texture2D> 에 담고 이것을 한방에 지움 

 => 결과 : 잘 소거됨


using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class MemoryTest1 : MonoBehaviour {

    private static string TestFileName = "test.jpg";
    public Texture2D TestTexture = null;
    public List<Texture2D> txs = new List<Texture2D>();

    void Start () {

        System.IO.File.WriteAllBytes( TestFileName , TestTexture.EncodeToJPG());

    }

    void OnGUI()
    {
        GUI.Label(new Rect(0,0,Screen.width , 30) ,"loaded texture  : " + txs.Count);

        if (GUI.Button(new Rect(0, 30, Screen.width / 4, 30), "Create"))
        {
            CreateTexture();
        }
        if (GUI.Button(new Rect(0, 60, Screen.width / 4, 30), "Delete All"))
        {
            DeleteTexture();
        }
    }

    void Update () {
    }

    private void CreateTexture()
    {
        StartCoroutine( LoadTexture());
    }

    WWW loader;
    IEnumerator LoadTexture()
    {
        loader = new WWW(@"file://" + TestFileName);
        yield return loader;
        txs.Add(loader.texture);
        Debug.Log("Texture Load");
    }


    /// <summary>
    /// 완벽 소거
    /// </summary>
    private void DeleteTexture()
    {
        int len = txs.Count;
        for (int i = 0; i < len; i++)
        {
            Texture2D.DestroyImmediate(txs[i]);
        }
        txs.Clear();
    }
}









Test2 : 큐브를 만들고 그것을 복제 하여 로드된 텍스쳐를 씌운다음 텍스쳐를 한방에 제거함. 

 => 결과 : 일부만 제거됨. 



using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class MemoryTest2 : MonoBehaviour {

    private static string TestFileName = "test.jpg";

    public GameObject Parent;
    public GameObject TargetObject;
    public Texture2D TestTexture = null;

    private List<Texture2D> txs = new List<Texture2D>();
    // Use this for initialization
    void Start () {
        System.IO.File.WriteAllBytes(TestFileName, TestTexture.EncodeToJPG());
    }
    
    // Update is called once per frame
    void Update () {
        

        Parent.transform.Rotate(1, 1, 1);
    }

    void OnGUI()
    {
        GUI.Label(new Rect(0,0,Screen.width , 30) ,"loaded texture  : " + txs.Count);
        if (GUI.Button(new Rect(0, 30, Screen.width / 4, 30), "Create"))
        {
            CreateTexture();
        }
        if (GUI.Button(new Rect(0, 60, Screen.width / 4, 30), "Delete All"))
        {
            DeleteTexture();
        }
    }

    private void CreateTexture()
    {
        GameObject cloneCube = (GameObject)GameObject.Instantiate(TargetObject, new Vector3(Random.Range(-3f, 3f), Random.Range(-3f, 3f), Random.Range(-3f, 3f)), Quaternion.identity);
        cloneCube.transform.parent = Parent.transform;
        StartCoroutine(LoadTexture(cloneCube));
    }

    WWW loader;
    IEnumerator LoadTexture(GameObject target)
    {
        loader = new WWW(@"file://" + TestFileName);
        yield return loader;
        target.renderer.material.mainTexture = loader.texture;
        txs.Add(loader.texture);
    }


    /// <summary>
    /// 일부 소거 됨 그러나 화면상에는 지워지지 않았음.
    /// </summary>
    private void DeleteTexture()
    {
        int len = txs.Count;
        for (int i = 0; i < len; i++)
        {
            Texture2D.DestroyImmediate(txs[i]);
        }
        txs.Clear();
    }
}






Test3 : 큐브를 만들고 텍스쳐를 씌운다음 오브젝트만 지움 

=> 결과 : 전혀 소거 되지 않음



using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class MemoryTest3 : MonoBehaviour
{

    private static string TestFileName = "test.jpg";

    public GameObject Parent;
    public GameObject TargetObject;
    public Texture2D TestTexture = null;

    //private List<Texture2D> txs = new List<Texture2D>();
    private List<GameObject> objs = new List<GameObject>();
    // Use this for initialization
    void Start()
    {
        System.IO.File.WriteAllBytes(TestFileName, TestTexture.EncodeToJPG());
    }

    // Update is called once per frame
    void Update()
    {
        Parent.transform.Rotate(1, 1, 1);
    }

    void OnGUI()
    {
        GUI.Label(new Rect(0, 0, Screen.width, 30), "loaded texture  : " + objs.Count);

        if (GUI.Button(new Rect(0, 30, Screen.width / 4, 30), "Create"))
        {
            CreateTexture();
        }
        if (GUI.Button(new Rect(0, 60, Screen.width / 4, 30), "Delete All"))
        {
            DeleteTexture();
        }
    }

    private void CreateTexture()
    {
        GameObject cloneCube = (GameObject)GameObject.Instantiate(TargetObject, new Vector3(Random.Range(-3f, 3f), Random.Range(-3f, 3f), Random.Range(-3f, 3f)), Quaternion.identity);
        cloneCube.transform.parent = Parent.transform;
        StartCoroutine(LoadTexture(cloneCube));
    }

    WWW loader;
    IEnumerator LoadTexture(GameObject target)
    {
        loader = new WWW(@"file://" + TestFileName);
        yield return loader;
        target.renderer.material.mainTexture = loader.texture;
        objs.Add(target);
    }


    /// <summary>
    /// 전혀 소거 되지 않음.
    /// </summary>
    private void DeleteTexture()
    {
        int len = objs.Count;
        for (int i = 0; i < len; i++)
        {
            GameObject.DestroyImmediate(objs[i]);
        }
        objs.Clear();
        objs = new List<GameObject>();
    }
}



Test4 : 큐브를 만들고 텍스쳐와 오브젝트를 지움.

=> 결과 : 잘 소거됨



using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class MemoryTest4 : MonoBehaviour
{
    private static string TestFileName = "test.jpg";

    public GameObject Parent;
    public GameObject TargetObject;
    public Texture2D TestTexture = null;

    private List<GameObject> objs = new List<GameObject>();
    void Start()
    {
        System.IO.File.WriteAllBytes(TestFileName, TestTexture.EncodeToJPG());
    }

    void Update()
    {
        Parent.transform.Rotate(1, 1, 1);
    }

    void OnGUI()
    {
        GUI.Label(new Rect(0, 0, Screen.width, 30), "loaded texture  : " + objs.Count);

        if (GUI.Button(new Rect(0, 30, Screen.width / 4, 30), "Create"))
        {
            CreateTexture();
        }
        if (GUI.Button(new Rect(0, 60, Screen.width / 4, 30), "Delete All"))
        {
            DeleteTexture();
        }
    }

    private void CreateTexture()
    {
        GameObject cloneCube = (GameObject)GameObject.Instantiate(TargetObject, new Vector3(Random.Range(-3f, 3f), Random.Range(-3f, 3f), Random.Range(-3f, 3f)), Quaternion.identity);
        cloneCube.transform.parent = Parent.transform;
        StartCoroutine(LoadTexture(cloneCube));
    }

    WWW loader;
    IEnumerator LoadTexture(GameObject target)
    {
        loader = new WWW(@"file://" + TestFileName);
        yield return loader;
        target.renderer.material.mainTexture = loader.texture;
        objs.Add(target);
    }


    /// <summary>
    /// 잘 소거 됨
    /// </summary>
    private void DeleteTexture()
    {
        int len = objs.Count;
        for (int i = 0; i < len; i++)
        {
            Texture2D.DestroyImmediate((Texture2D)objs[i].renderer.material.mainTexture);
            GameObject.DestroyImmediate(objs[i]);
        }
        objs.Clear();
        objs = new List<GameObject>();
    }
}

ㅁㅁ


Test5 : Test4의 상황에서 텍스쳐 리스트를 만들고 명시적으로 지워주지 않았음 
=> 결과 : 일부만 소거됨 , 만약 DeleteTexture 의 주석을 제거 한다면 완벽 제거됨


using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class MemoryTest5 : MonoBehaviour
{

    private static string TestFileName = "test.jpg";

    public GameObject Parent;
    public GameObject TargetObject;
    public Texture2D TestTexture = null;

    private List<Texture2D> txs = new List<Texture2D>();
    private List<GameObject> objs = new List<GameObject>();
    void Start()
    {
        System.IO.File.WriteAllBytes(TestFileName, TestTexture.EncodeToJPG());
    }

    void Update()
    {
        Parent.transform.Rotate(1, 1, 1);
    }

    void OnGUI()
    {
        GUI.Label(new Rect(0, 0, Screen.width, 30), "loaded texture  : " + objs.Count);

        if (GUI.Button(new Rect(0, 30, Screen.width / 4, 30), "Create"))
        {
            CreateTexture();
        }
        if (GUI.Button(new Rect(0, 60, Screen.width / 4, 30), "Delete All"))
        {
            DeleteTexture();
        }
    }

    private void CreateTexture()
    {
        GameObject cloneCube = (GameObject)GameObject.Instantiate(TargetObject, new Vector3(Random.Range(-3f, 3f), Random.Range(-3f, 3f), Random.Range(-3f, 3f)), Quaternion.identity);
        cloneCube.transform.parent = Parent.transform;
        StartCoroutine(LoadTexture(cloneCube));
    }

    WWW loader;
    IEnumerator LoadTexture(GameObject target)
    {
        loader = new WWW(@"file://" + TestFileName);
        yield return loader;
        target.renderer.material.mainTexture = loader.texture;
        objs.Add(target);
        txs.Add(loader.texture);
    }


    /// <summary>
    /// 일부만 소거됨
    /// </summary>
    private void DeleteTexture()
    {
        int len = objs.Count;
        for (int i = 0; i < len; i++)
        {
            Texture2D.DestroyImmediate((Texture2D)objs[i].renderer.material.mainTexture);
            GameObject.DestroyImmediate(objs[i]);

        }
        objs.Clear();
        objs = new List<GameObject>();

        //for (int i = 0; i < txs.Count; i++)
        //{
        //    Texture2D.DestroyImmediate(txs[i]);
        //}
        txs.Clear();
        txs = new List<Texture2D>();
    }
}


Yamecoder 야매코더_
unity3d 2014.09.10 16:09
Powerd by Tistory, designed by criuce
rss