演示unity内存管理机制的缺陷
技术:unity3d + c#
概述
这是最近做项目时发现的一个内存管理机制上的一个缺陷,但是我并不知道这究竟是不是一个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"); } }
三、运行效果
我们先生成一大堆对象,点击游戏中的创建对象按钮生成一大堆对象,如下图:
然后点击删除对象,并且跳转场景重新进入此场景,如下图
我们会发现,虽然我们已经Destroy了全部的TestObj附着的GameObject,但是内存中却还会一直驻留着大量没有清理的内存。
其实原因在于我每次新创建的TestObj都把其中的方法dddd放进了static List<UnityEngine.Events.UnityAction> m_texList = new List<UnityEngine.Events.UnityAction>();
而这个是一个静态成员,会一直存在于游戏的整个过程,只要它没有被销毁,则TestObj都会存在于内存中,这虽然能解决新手程序员常写出来的野指针问题,但是却实在是造成内存泄漏。
四、其他补充
打开项目后,项目截图如下:
本实例支付的费用只是购买源码的费用,如有疑问欢迎在文末留言交流,如需作者在线代码指导、定制等,在作者开启付费服务后,可以点击“购买服务”进行实时联系,请知悉,谢谢
手机上随时阅读、收藏该文章 ?请扫下方二维码