unity里GameObject和Texture的内存归属

GameObject 与 Native 组件(C++ 端):

1.每一个 GameObject,以及内置组件(如 Transform、MeshRenderer、Rigidbody 等),其核心数据结构都是用 C++ 实现的。

它们存在于 Unity 的 Native 内存 中,受 Unity 底层内存管理器控制,不由 C# 的垃圾回收器(GC)直接回收。

2.MonoBehaviour 与自定义脚本(Mono/IL2CPP 托管堆)以及脚本中定义的 C# 变量(如 int、string、自定义类对象等)是分配在 Mono 托管堆 上的,受 C# 的 GC 管理。

3.你的 C# 代码中访问一个 GameObject 时,会在mono上分配一个这个GameObject的wrap包装器,所以频繁地创建和销毁 GameObject(Instantiate / Destroy)会产生大量的 C# 包装器对象以及底层的Native内存分配。

4.如果你在 C# 中用静态变量强引用了 GameObject 或其组件的包装器,会导致底层的 Native 对象无法被 Unity 正常卸载,从而引发严重的内存泄漏。

5.Destroy(gameObject) 时Unity 会在当前帧的末尾销毁底层的 C++ 对象,并释放其占用的部分 Native 内存这部分内存会返回给 Unity 缓存(Cache),不会把释放的内存立即交还给操作系统(OS),你想强制 Unity 把未使用的 Native 内存交还给系统需要调用 Resources.UnloadUnusedAssets(),或者在场景切换时触发,这在移动端开销较大,不建议频繁调用。

6.gameobject被Destroy 触发后,C# 层的包装器(Wrapper)失去了底层 C++ 对象的支撑,变成了"死对象"(指向空指针)。但它们占用的托管堆内存依然被占用,只有当触发了 GC(Garbage Collection),Mono 内存管理器扫描到这些包装器不再被任何强引用持有时,才会将它们从托管堆中清理掉,腾出堆空间,但是 GC 释放了托管堆内存,Mono 堆的总大小(Heap Size)在移动端很少主动向 OS 归还堆内存,而是留着给后续的 C# 对象继续复用。

7.Texture 大头在Native 内存,即使你把 C# 层的 Texture2D 变量置为 null,如果底层的 Native 对象没有被 Destroy 或 Unload,这部分内存依然会被占用。在 C# 中你为了获取到的那个 Texture2D 对象本身的C# 包装器(Wrapper)是归属到托管堆,如果你通过 LoadAsset 获取了纹理实例,必须调用Resources.UnloadAsset(texture)这是释放单个纹理资源最标准的方法。它会立即卸载该资源在 Native 内存中的像素数据。

相关推荐
点心的游戏开发世界26 分钟前
Unity C# 脚本学习笔记:命名空间与 using
学习·unity·c#
2601_962071571 小时前
【Java报错已解决】org.springframework.beans.factory.BeanCreationException
java·开发语言
zww89491112 小时前
酒馆预约系统开发实战:从需求分析到上线全流程指南
java·eclipse
点心的游戏开发世界2 小时前
Unity C# 脚本学习笔记:泛型
学习·unity·c#
zww89491114 小时前
匿名树洞系统开发实战:从需求分析到部署指南
java·eclipse
黑马程序员毕设5 小时前
基于Java的医院药品管理系统的优化设计与实现
java·开发语言·spring boot·小程序·架构·课程设计·毕设
木井巳6 小时前
【BFS/DFS 解决 FloodFill 算法】太平洋大西洋水流问题
java·算法·leetcode·深度优先·广度优先·宽度优先·推荐算法
白山编程大哥6 小时前
Java 集合算法:从排序、查找到底层原理的实战指南
java·python·算法
devpotato6 小时前
缓存与数据库更新顺序不一致问题
java·数据库·redis
xcl09256 小时前
酒馆预约系统开发实战:从需求分析到上线全流程指南
java·spring boot·需求分析