演示unity内存管理机制的缺陷

发布时间:2017-09-21

概述

这是最近做项目时发现的一个内存管理机制上的一个缺陷,但是我并不知道这究竟是不是一个bug,因为他可以造成内存泄漏,但是却能避开野指针。

详细

一、准备工作

解压memerytest.zip压缩包,用Unity 5.3.3f1 (64-bit)及以上版本打开项目,打开Main场景,就可以测试了。

二、程序实现

第一步,我先创建一个类TestObj,类TestObj在生成时会申请一大块内存创建一个纹理,并且类TestObj中有一个公开方法dddd(原谅我的随便)如下:

using UnityEngine;
using System.Collections;

public class TestObj : MonoBehaviour {
    public Texture2D tx2d = null;
    public int xxx = 112;
    public dui aa;
	// Use this for initialization
	void Awake () {
        tx2d = new Texture2D(2048, 1536, TextureFormat.ARGB32, false, true);
        aa = new dui();

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

    public void dddd()
    {

    }
}

第二步,我们需要一个生成TestObj的测试类,这个测试类如下:

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.UI;
using UnityEngine.SceneManagement;

public class MemeryTesr : MonoBehaviour {
    List<GameObject> m_objList = new List<GameObject>();
    static List<UnityEngine.Events.UnityAction> m_texList = new List<UnityEngine.Events.UnityAction>();
	// Use this for initialization
	void Start () {
	}
	
	// Update is called once per frame
	void Update () {
	
	}

    public void CreateObj()
    {
        GameObject obj = new GameObject("new obj");
        TestObj t2d = obj.AddComponent<TestObj>();
        m_objList.Add(obj);
        m_texList.Add(t2d.dddd);
    }

    public void DestroyObj()
    {
        if (m_objList.Count > 0)
        {
            Destroy(m_objList[m_objList.Count - 1]);
            m_objList.RemoveAt(m_objList.Count - 1);
        }

        Resources.UnloadUnusedAssets();
    }

    public void jumpScene()
    {
        SceneManager.LoadScene("load");
    }

}


三、运行效果

我们先生成一大堆对象,点击游戏中的创建对象按钮生成一大堆对象,如下图: 

11.jpg

然后点击删除对象,并且跳转场景重新进入此场景,如下图

12.jpg

我们会发现,虽然我们已经Destroy了全部的TestObj附着的GameObject,但是内存中却还会一直驻留着大量没有清理的内存。

其实原因在于我每次新创建的TestObj都把其中的方法dddd放进了static List<UnityEngine.Events.UnityAction> m_texList = new List<UnityEngine.Events.UnityAction>();

而这个是一个静态成员,会一直存在于游戏的整个过程,只要它没有被销毁,则TestObj都会存在于内存中,这虽然能解决新手程序员常写出来的野指针问题,但是却实在是造成内存泄漏。

四、其他补充

打开项目后,项目截图如下:

1.jpg


本实例支付的费用只是购买源码的费用,如有疑问欢迎在文末留言交流,如需作者在线代码指导、定制等,在作者开启付费服务后,可以点击“购买服务”进行实时联系,请知悉,谢谢
手机上随时阅读、收藏该文章 ?请扫下方二维码