UNITY Destroy()和DestroyImadiate()都不会立即释放对象内存
如题,destroyimadiate是立即将物体从场景hierachy中移除,并标记为 "null",注意 是带引号的null。这是UNITY内部的一个处理技巧。关于这个技巧有很争议。
destroy要等到帧末才会将物体从场景层级中移除并标记为"null"。
不管如何,二者都只是UNITY引擎层面的标记与处理,但在.NET底层,对象的内存都没有释放,只有手动GC.COLLECT或等待NET去GC时才会释放掉对象内存。
测试代码如下:点ADD按钮不断创建对象,点DEL按钮清除所有对象,通过观察进程内存数值来察看对象内存是否释放。
1 using System.Collections; 2 using System.Collections.Generic; 3 using System.Diagnostics; 4 using UnityEngine; 5 using UnityEngine.UI; 6 7 public class MyGo : MonoBehaviour 8 { 9 byte[] data = new byte[83000]; 10 } 11 public class testad : MonoBehaviour { 12 13 Transform objs; 14 Text txt; 15 16 Process proc; 17 // Use this for initialization 18 void Start () { 19 var btnadd = transform.Find("btnAdd").GetComponent<Button>(); 20 btnadd.onClick.AddListener(OnClckAdd); 21 var btndel = transform.Find("btnDel").GetComponent<Button>(); 22 btndel.onClick.AddListener(OnClckDel); 23 24 objs = transform.Find("objs"); 25 26 txt = transform.Find("Text").GetComponent<Text>(); 27 proc = Process.GetCurrentProcess(); 28 } 29 30 void OnClckAdd() 31 { 32 for (int i = 0; i < 20; ++i) 33 { 34 var go = new GameObject(); 35 go.AddComponent<MyGo>(); 36 go.transform.SetParent(objs); 37 } 38 } 39 40 void OnClckDel() 41 { 42 for (int i = objs.childCount - 1; i >= 0; i--) 43 { 44 GameObject.DestroyImmediate(objs.GetChild(i).gameObject); 45 } 46 47 System.GC.Collect(); 48 } 49 // Update is called once per frame 50 51 float timer = 0; 52 void Update () { 53 if (timer > 0.5f) 54 { 55 timer = 0; 56 txt.text = ((int)(proc.WorkingSet64 / 1024)).ToString(); 57 } 58 timer += Time.deltaTime; 59 } 60 }