Unity3d使用内存:加载和卸载预制件

时间:2014-06-06 08:10:01

标签: ios memory unity3d assets

我真的需要帮助! 我无法理解如何使用预制件和卸载。

我有下一个情况。

我在Xcode上运行我的应用程序。 Unity版本4.3.1 Pro。 使用with监视内存: Xcode Debug Navigator Xcode仪器 Unity Profiler

我接下来的步骤:

0)Unity从空场景开始。

已用内存XCODE Debug Navigator:11 mb仪器:26.4 mb Unity Profiler:使用总计13.2保留总计13.7

1)从资源文件夹

加载预制件
prefab = Resources.Load("Room1"); 

已用内存XCODE Debug Navigator:30.8 mb仪器:49.54 mb Unity Profiler:总共使用 19.8保留总计20.4

2)实例化预制件

go = (GameObject)Instantiate(prefab); 
go.name = "Room1"; 

XCODE Debug Navigator:31.2 mb仪器:50 mb Unity Profiler:总共20个预留总数20.7

3)销毁场景中的所有对象 - 内存未更改

Transform[] tr = FindObjectsOfType<Transform>(); 
for (int i = 0; i < tr.Length; i++) 
{ 
    GameObject goo = tr.gameObject; 
    if (goo.name != "Main Camera") 
    {
        Destroy(goo); 
        goo = null;
    } 
} 

XCODE Debug Navigator:31.1 mb仪器:49.93 mb Unity Profiler:总共19.8保留总计20.4

4)调用Resources.UnloadUnusedAssets(); - 内存未更改

5)致电System.GC.Collect(); - 内存未更改

6)调用预装Resources.UnloadAsset(prefab);的UnloadAsset - 内存未更改

7)致电Resources.UnloadUnusedAssets(); - 内存部分清理

XCODE Debug Navigator:21.9 mb仪器:40.79 mb Unity Profiler:总共13.2保留总计13.9

在我看到的分析器中,删除了预制件中使用的所有纹理

8)System.GC.Collect(); - 记忆没有改变

9)加载空场景 - 内存未更改

这是另一个有趣的时刻:

当应用程序进入后台并启动另一个应用程序时,使用的RAM的大小会大大减少,当我调用unity app时 - 内存会变为第一个大小并显示空白场景。

我有下一个问题:

1)为什么在删除prefab并调用UnloadUnusedAssets后没有完全清除内存 - 我们可以在Instruments和Xcode中看到它 - 但在Profiler中我们看到,该内存几乎完全免费?

2)将内存清理到初始大小是真的吗?

3)我所有的步骤还是我做错了什么?

您可以在此处下载测试项目: http://gfile.ru/aa5on

非常感谢您的回复。

2 个答案:

答案 0 :(得分:8)

序言

了解RAM使用情况很好。但是,问题是:到目前为止,您是否遇到过内存使用方面的任何问题?如果没有,那你所做的就是为时过早。

一些想法

以下是您可以考虑的一些想法:

  1. 重要文章:http://docs.unity3d.com/Manual/MobileProfiling.html
  2. 有Unity内存和单声道内存。 Mono永远不会回放操作系统内存:
      

    一旦分配了一定数量的内存,它就会保留为单声道,而不适用于操作系统。即使你发布它,它也只能在内部用于Mono,而不能用于操作系统。 Profiler中的堆内存值只会增加,永不减少。

  3.   
  4. 预制件和游戏对象只是一大堆链接,所以它们没有资源那么大的内存占用。
  5.   
  6. Object.Destroy doesn't destroy object instantly

      

    实际对象破坏始终延迟到当前Update循环之后,但总是在渲染之前完成。

  7. Resources.UnloadUnusedAssets是异步的。它不会立即卸载所有内容。
  8. Unity的文档中未提及Resources.UnloadAsset(Object assetToUnload)将卸载assetToUnload引用的资源。
  9. 解释

    我不能称自己为内存管理专家(Unity和Mono)。但这是我如何理解正在发生的事情:

    1.   

      1)从资源文件夹

      加载预制件

      Prefab加载了它引用的所有资源。内存使用量增加。现在一切都很清楚了。

    2.   

      2)实例化预制件

      内存使用量增加了一点,以保留预制克隆。

    3.   

      3)销毁场景中的所有对象 - 内存未更改

      这里有趣的事情:)实际上,根据Unity的分析器,内存使用情况发生了变化:它与预制实例化之前的情况相同。因此,看起来Unity发布了与预制实例直接相关的内容。但是,正如所说的那样,单声道不会将内存返回给操作系统(即使它确实没有时间也可以这样做)。

    4.   

      4)调用Resources.UnloadUnusedAssets(); - 记忆未改变

      Resources.UnloadUnusedAssets无法在此处卸载任何内容,因为仍然没有未使用的资产:虽然对象已标记为已销毁,但实际的垃圾收集尚未发生。

    5.   

      5)调用System.GC.Collect(); - 记忆未改变。

      这是因为它的内存由mono管理。

    6.   

      6)调用UnloadAsset预制的Resources.UnloadAsset(prefab);

      我相信内存使用量在这里有所下降(100K-200K左右),但你没有注意到它。但是,正如我上面提到的,UnloadAsset将不会卸载作为参数传递给UnloadAsset的对象引用的资源。

    7.   

      7)调用Resources.UnloadUnusedAssets(); - 内存部分清理

      在步骤5中,您调用了GC.Collect(),已经发生了收集,现在有些Unity资产没有引用它们。因此,它们最终可以被释放。这就是记忆被释放的原因。

    8.   

      8)System.GC.Collect(); - 记忆未改变

      上面解释

    9.   

      9)加载空场景 - 内存未更改

      所有可以释放的东西已经被释放了。因此,内存使用量没有变化。

答案 1 :(得分:0)

好吧,也许我需要从另一方面查看问题 - 在Unity应用程序暂停时清理内存?也许有人知道,怎么办? 或者在我尝试开始暂停应用程序时重新启动它。