通过unityEngine命名空间中的接口分配的内存,将会通过unity分配在Native堆: unity的资源;
通过System命名空间中的接口分配的内存,将会通过MonoRuntime分配在Mono堆: unity的C#代码;
代码会通过Mono的GC机制自动回收内存垃圾,unity是使用基于Mono的C#作为语言,它是基于Garbage Collection
机制的内存托管语言,但是,即便是内存托管了,也会存在内存泄露,因为GC的算法并不是万能的;
在unity环境下,Mono堆内存的占用只会增加不会减少;具体来说,可将Mono堆理解为一个内存池,每次Mono堆内存的申请都会在池内进行分配,释放的时候也是归还给池,而不会归还给操作系统。如果某次分配发现池内存不够了,则会对池进行扩建:向操作系统申请更多的内存来扩大池,以满足该次的内存分配。需要注意的是,每次对池的扩建都是一次较大的内存分配,每次扩建都会将池扩大6-10M左右
代码垃圾GC会自动处理,unity资源就需要手动清除了:Resources.UnloadUnusedAssets;该方法只会清除没用的资源,在调用该方法的时候也会自动调用GC的接口:GC.Collect;而另外一种清除资源的方法:Resources.UnloadAsset不会区分是不是垃圾资源,都会干掉
Resources.UnloadUnusedAssets只是标记,并不清理,并且不是标记为空闲(这个是GC干的,就是mono的清理,因为mono不归还内存给os,只在mono层标记为空闲,os层还是使用中),只是把该块内存降级,让gc清理。所以destroy an object后调Resources.UnloadUnusedAssets并没有卵用,要等GC来了才生效。
System.GC.Collect() 遵循垃圾回收机制,分层回收 。
.Net不推荐手动在代码里面调用,因为它会自己在合适的时候调用;调用这句代码会占用很大的cpu资源,因为它会查找当前项目代码中所有没有被引用的资源内存,然后开辟一个新的内存层,再把删掉后的有引用资源的内存复制到新的内存层。
Resources 加载的资源需要释放的时候调用 Resources.UnloadUnusedAssets();
WWW 加载资源之后最好调用WWW的Dispose接口,using;
网友评论