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

概述

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

详细

一、准备工作

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

二、程序实现

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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的测试类,这个测试类如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
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

 

注:本文著作权归作者,由demo大师发表,拒绝转载,转载需要作者授权

 

posted on   demo例子集  阅读(227)  评论(0编辑  收藏  举报

(评论功能已被禁用)
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· Windows编程----内核对象竟然如此简单?

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示