先看一个真机测试实例:

两个物体放在同一个Group里面

只创建Cube时,内存资源中只有Cube的材质球和贴图

同时创建了Cube和Sphere,内存资源中拥有两个材质球和贴图

此时只删除Cube,Cube的材质球和贴图不会被释放,当然场景内存(SceneMemory)肯定是释放了的

只有把Sphere也释放掉才会同时将两个材质球和贴图都从资源内存中释放。

所以一个Group中的资源不会一起加载进资源,但是只要加载了进来资源,只有该Group全部引用都被删除之后,

资源才会被一起释放掉

测试代码:


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;public class testaa : MonoBehaviour
{private List<GameObject> Cubelist = new List<GameObject>();private List<GameObject> Spherelist = new List<GameObject>();public void CreateCube(){Addressables.InstantiateAsync("Cube").Completed += delegate(AsyncOperationHandle<GameObject> handle){  Cubelist.Add(handle.Result);};}public void CreateSphere(){Addressables.InstantiateAsync("Sphere").Completed += delegate(AsyncOperationHandle<GameObject> handle){  Spherelist.Add(handle.Result);};}public void ClearCube(){for (int i = 0; i < Cubelist.Count; i++){Addressables.Release(Cubelist[i]);}Cubelist.Clear();}public void ClearSphere(){for (int i = 0; i < Spherelist.Count; i++){Addressables.Release(Spherelist[i]);}Spherelist.Clear();}
}

下面是官方文档对Addressable内存的讲解,自己根据理解翻译了一下。

Mirroring load and unload

When working with Addressable Assets, the primary way to ensure proper memory management is to mirror your load and unload calls correctly. How you do so depends on your asset types and load methods. In all cases, however, the release method can either take the loaded asset, or an operation handle returned by the load. For example, during Scene creation (described below) the load returns a AsyncOperationHandle<SceneInstance>, which you can release via this returned handle, or by keeping up with the handle.Result (in this case, a SceneInstance).

镜像加载和卸载(有加载就要有卸载)

在使用Addressable时,正确的内存管理主要方法是成对儿地调用加载和卸载。如何这样做取决于您的资源类型和加载方法。但是,在所有情况下,release方法接受的参数既可以是加载好的资源,也可以是加载资源时的句柄。例如,在场景创建期间(如下所述),加载返回一个AsyncOperationHandle<SceneInstance>,您可以通过这个返回的句柄来释放它,或者通过这个句柄包含的实例(handle.Result) 释放它(在本例中是一个SceneInstance)。

Asset loading

To load an asset, use Addressables.LoadAssetAsync or Addressables.LoadAssetsAsync.

This loads the asset into memory without instantiating it. Every time the load call executes, it adds one to the ref-count for each asset loaded. If you call LoadAssetAsync three times with the same address, you will get three different instances of an AsyncOperationHandle struct back, all referencing the same underlying operation. That operation has a ref-count of three for the corresponding asset. If the load succeeds, the resulting AsyncOperationHandle struct contains the asset in the .Result property. You can use the loaded asset to instantiate using Unity's built-in instantiation methods, which does not increment the Addressables ref-count.

资源加载

要加载资源,请使用Addressables.LoadAssetAsync或Addressables.LoadAssetsAsync。

这将在不实例化的情况下将资源加载到内存中。每次执行load调用时,它都会为每个加载的资源添加一个引用计数(ref-count)。如果使用相同的地址调用LoadAssetAsync三次,您将获得三个不同的AsyncOperationHandle的回调实例,但是它们都引用相同的底层操作。该操作对应的资源的ref-count为3。如果加载成功,返回的AsyncOperationHandle的. result属性就是我们要的资源。您可以使用这个加载的资源通过Unity的内置实例化方法(指GameObject.Instantiate)来生成它,它不会增加ref-count。

To unload the asset, use the Addressables.Release method, which decrements the ref-count. When a given asset's ref-count is zero, that asset is ready to be unloaded, and decrements the ref-count of any dependencies.

Note: The asset may or may not be unloaded immediately, contingent on existing dependencies. For more information, read the section on when memory is cleared.

要卸载资源,请使用Addressables.Release 方法,减少 ref-count。当给定资源的ref-count为0时,该资源就准备好被卸载了,并减少所有依赖项的ref-count。

注意:根据现有的依赖关系,资源可以立即卸载,也可以不立即卸载。有关更多信息,请阅读“何时清除内存”一节。

Scene loading

To load a Scene, use Addressables.LoadSceneAsync. You can use this method to load a Scene in Single mode, which closes all open Scenes, or in Additive mode (for more information, see documentation on Scene mode loading.

To unload a Scene, use Addressables.UnloadSceneAsync, or open a new Scene in Single mode. You can open a new Scene by either using the Addressables interface, or using the SceneManager.LoadScene or SceneManager.LoadSceneAsync methods. Opening a new Scene closes the current one, properly decrementing the ref-count.

场景加载

要加载一个场景,使用Addressables.LoadSceneAsync。支持Single mode和Additive mode。

要卸载一个场景,使用Addressables.UnloadSceneAsync,或在直接使用Single mode打开一个新场景。这里说的打开新场景,既可以使用Addressables接口也可以使用SceneManager.LoadScene或SceneManager.LoadSceneAsync方法。打开一个新场景应当关闭当前场景,适当减少ref-count。

GameObject instantiation

To load and instantiate a GameObject asset, use Addressables.InstantiateAsync. This instantiates the Prefab located by the specified location parameter. The Addressables system will load the Prefab and its dependencies, incrementing the ref-count of all associated assets.

GameObject实例化

要加载并实例化GameObject资源,请使用Addressables.InstantiateAsync。这个实例化的方法可以添加指定的参数(于GameObject.Instantiate类似,看下API就知道了)。Addressables 系统将加载Prefab及其所有依赖项,并给所有这些相关资源增加的ref-count。

Calling InstantiateAsync three times on the same address results in all dependent assets having a ref-count of three. Unlike calling LoadAssetAsync three times, however, each InstantiateAsync call returns an AsyncOperationHandle pointing to a unique operation. This is because the result of each InstantiateAsync is a unique instance. Another distinction between InstantiateAsync and other load calls is the optional trackHandle parameter. When set to false, you must keep the AsyncOperationHandle to use while releasing your instance. This is more efficient, but requires more development effort.

对同一个地址调用三次InstantiateAsync会导致所有相关资源的ref-count为3。但是,与三次调用LoadAssetAsync不同的是每个InstantiateAsync调用都返回一个指向唯一操作的AsyncOperationHandle。这是因为每个InstantiateAsync的结果都是唯一的实例。InstantiateAsync和其他加载调用相比另一个区别在于有一个可选的trackHandle参数。当设置为false时,就必须通过AsyncOperationHandle的句柄来释放资源,而不能再通过它的.Result了(默认为true,于本文第一段讲到的卸载参数相呼应)。

To destroy an instantiated GameObject, use Addressables.ReleaseInstance, or close the Scene that contains the instantiated object. This Scene can have been loaded (and thus closed) in Additive or Single mode. This Scene can also have been loaded using either the Addressables or SceneManagement API. As noted above, if you set trackHandle to false, you can only call Addressables.ReleaseInstance with the handle, not with the actual GameObject.

若要销毁实例化的GameObject,请使用Addressables.ReleaseInstance或关闭包含实例化对象的场景。此场景应该是通过Additive模式或者Single模式已经加载好的场景(这样才能执行卸载)。这个场景既可以是使用Addressables API 也可以是SceneManagement API加载好的。如上所述,如果将trackHandle设置为false,则只能调用Addressables.ReleaseInstance来释放加载句柄,而不是使用实际的GameObject。

Note: If you call Addressables.ReleaseInstance on an instance that was not created using the Addressables API, or was created with trackHandle==false, the system detects that and returns false to indicate that the method was unable to release the specified instance. The instance will not be destroyed in this case.

注意:如果您调用Addressables.ReleaseInstance传入的实例并不是使用Addressables API创建的实例,或者使用trackHandle==false创建的实例,系统会检测到这一点并返回false,以指示该方法无法释放指定的实例。在这种情况下,实例不会被销毁。

Addressables.InstantiateAsync has some associated overhead, so if you need to instantiate the same objects hundreds of times per frame, consider loading via the Addressables API, then instantiating through other methods. In this case, you would call Addressables.LoadAssetAsync, then save the result and call GameObject.Instantiate() for that result. This allows flexibility to call Instantiate in a synchronous way. The downside is that the Addressables system has no knowledge of how many instances you created, which can lead to memory issues if not properly managed. For example, a Prefab referencing a texture would no longer have a valid loaded texture to reference, causing rendering issues (or worse). These sorts of problems can be hard to track down as you may not immediately trigger the memory unload (see section on clearing memory, below).

Addressables.InstantiateAsync有一些相关的开销,所以如果需要在每一帧中实例化数百次相同的对象,可以考虑通过Addressables API加载,然后通过其他方法实例化。在这种情况下,您将调用Addressables.LoadAssetAsync,然后保存结果并为该结果调用GameObject.Instantiate()。这允许以同步方式灵活地调用实例化。缺点是Addressables系统不知道您创建了多少实例,如果管理不当,可能会导致内存问题。例如,一个Prefab引用了一个加载不正确或者已经卸载的纹理,会导致渲染问题(或更糟)。这类问题很难跟踪,因为您可能不会立即触发内存卸载(参见下面关于清除内存的部分)。

Data loading

Interfaces that do not need their AsyncOperationHandle.Result released, will still need the operation itself to be released. Examples of these would be Addressables.LoadResourceLocationsAsync and Addressables.GetDownloadSizeAsync. They load data that you can access until the operation is released. This release should be done via Addressables.Release.

数据加载

加载的数据在卸载时不需要释放.Result,但是需要卸载这个加载资源的句柄(就是理解为只能卸载句柄不能卸载.Result)。举个例子当使用

Addressables.LoadResourceLocationsAsync和 Addressables.GetDownloadSizeAsync加载到的数据,在其句柄被释放前都可以被访问到。释放需要通过Addressables.Release方法

Background interactions

Operations that do not return anything in the AsyncOperationHandle.Result field have have an optional parameter to automatically release the operation handle on completion. If you have no further need for one of these operation handles after it has completed, set the autoReleaseHandle parameter to true to make sure the operation handle is cleaned up. The scenario where you would want autoReleaseHandle to be false would be if you needed to check the Status of the operation handle after it has completed. Examples of these interfaces are Addressables.DownloadDependenciesAsync and Addressables.UnloadScene.

Background interactions?

如果AsyncOperationHandle.Result中不包含任何东西,这里有一个可选参数用于在完成时自动释放操作句柄。如果在这些操作句柄完成后,您不再需要这些操作句柄,则将autoReleaseHandle参数设置为true,以确保清除了操作句柄。如果需要在操作句柄完成后检查其状态,则将autoReleaseHandle设置为false。比如 Addressables.DownloadDependenciesAsync 和 Addressables.UnloadScene。

The Addressables Event Viewer

Use the Addressables Event Viewer window to monitor the ref-counts of all Addressables system operations. To access the window in the Editor, select Window > Asset Management > Addressables > Event Viewer.

Important: In order to view data in the Event Viewer, you must enable the Send Profiler Events setting in your AddressableAssetSettings object's Inspector.

Addressables事件查看器

使用Addressables事件查看器窗口监视所有Addressables系统操作的ref-counts。要访问编辑器中的窗口,请select Window > Asset Management > Addressables > Event Viewer。

重要提示:为了在事件查看器中查看数据,您必须在您的AddressableAssetSettings对象的检查器中启用Send Profiler Events设置。

The following information is available in the Event Viewer:

  • A white vertical line indicates the frame in which a load request occurred.
  • A blue background indicates that an asset is currently loaded.
  • The green part of the graph indicates an asset's current ref-count.

事件查看器提供以下信息:

一条白色的竖线表示每帧发生的加载请求。

蓝色背景表示当前已经加载的资源。

图中的绿色部分表示资源当前的ref-count。

Note that the Event Viewer is only concerned with ref-counts, not memory consumption (see section on clearing memory, below, for more information).

Listed under the Assets column, you will see a row for each of the following, per frame:

  • FPS: The frames per second count.
  • MonoHeap: The amount of RAM in use.
  • Event Counts: The total number of events in a frame.
  • Asset requests: Displays the reference count on an operation over time. If the asset request has any dependencies, a triangle appears that you can click on to view the children's request operations.

You can click the left and right arrows in order to step through the frames one by one, or click Current to jump to the latest frame. Press the + button to expand a row for more details.

请注意,事件查看器只关心ref-counts,而不关心内存消耗(有关清除内存的详细信息,请参阅下面的部分)。

在“Asset”栏下列出的每一帧中,您可以看到逐行看到每一个资源每一帧的情况:

FPS:每秒帧数。

MonoHeap:内存使用的总量。

Event Counts:一帧中事件的总数。

Asset requests:显示一个操作随时间的引用计数。如果资产请求有任何依赖项,则会出现一个三角形,您可以单击该三角形查看子请求操作。

您可以单击左箭头和右箭头逐帧观察,或者单击Current跳转到最新的帧。按+按钮展开一行以获得更多详细信息。

The information displayed in the Event Viewer is related to the build script you use to create Play mode data.

When using the Event Viewer, avoid the Use Asset Database built script because it does not account for any shared dependencies among the assets. Use the Simulate Groups script or the Use Existing Build script instead, but the latter is better suited for the Event Viewer because it gives a more accurate monitoring of the ref-counts.

事件查看器中显示的信息与在build script中选择的游戏模式有关(详细信息见 build script)

使用事件查看器时,应避免使用 Use Asset Database模式,因为它不考虑资产之间的任何依赖关系。使用Simulate Groups 或Use Existing Build模式,但是后者更适合于事件查看器,因为它可以更准确地监视ref-counts。

When is memory cleared?

An asset no longer being referenced (indicated by the end of a blue section in the profiler) does not necessarily mean that asset was unloaded. A common applicable scenario involves multiple assets in an asset bundle. For example:

  • You have three assets (tree, tank, and cow) in an asset bundle (stuff).
  • When tree loads, the profiler displays a single ref-count for tree, and one for stuff.
  • Later, when tank loads, the profiler displays a single ref-count for both tree and tank, and two ref-counts for the stuff bundle.
  • If you release tree, it's ref-count becomes zero, and the blue bar goes away.

何时清除内存?

不再被引用的资源(profiler面板中的蓝色部分)并不一定意味着资源产已被卸载。一个常见的应用场景涉及到一个资源包中包含多个资源。例如:

  • 您有三个资源(“树”,“坦克”,“牛”)在同一个资源包(“东西”)。
  • 当“树”加载时,“树”的ref-count +1,“东西”的ref-count +1。
  • 稍后,当“坦克”加载时,“树”和“坦克”的ref-count均为1,并且“东西”包的ref-count为2。
  • 如果你释放“树”,它的ref-count就会变成0。

In this example, the tree asset is not actually unloaded at this point. You can load an asset bundle, or its partial contents, but you cannot partially unload an asset bundle. No asset in stuff will unload until the bundle itself is completely unloaded. The exception to this rule is the engine interface Resources.UnloadUnusedAssets. Executing this method in the above scenario will cause tree to unload. Because the Addressables system cannot be aware of these events, the profiler graph only reflects the Addressables ref-counts (not exactly what memory holds). Note that if you choose to use Resources.UnloadUnusedAssets, it is a very slow operation, and should only be called on a screen that won't show any hitches (such as a loading screen).

在这个例子中,“树”资源实际上并没有被卸载。您可以加载资源包或其部分内容,但不能部分卸载资源包。在包本身完全卸载之前,所有资产都不会卸载。这个规则的例外是engine接口Resources.UnloadUnusedAssets。在上述场景中执行此方法将导致树卸载。因为Addressables系统不能识别这些事件,所以profiler 只反映Addressables的ref-counts (不完全反映内存中存在的内容)。注意,如果您选择使用Resources.UnloadUnusedAssets,这是一个非常慢的操作,应该只在一个不会显示任何游戏内容的屏幕调用(比如加载屏幕)。

Unity Addressable内存管理相关推荐

  1. Unity AssetBundle内存管理相关问题

    AssetBundle机制相关资料收集 最近网友通过网站搜索Unity3D在手机及其他平台下占用内存太大. 这里写下关于Unity3D对于内存的管理与优化. Unity3D 里有两种动态加载机制:一个 ...

  2. 刨根问底U3D---从Profile中窥探Unity的内存管理

    这篇文章包含哪些内容 这篇文章从Unity的Profile组件入手,来探讨一下Unity在开发环境和正式环境中的内存使用发面的一些区别, 并且给出了最好控制内存的方法(我想你已经知道了...Prefa ...

  3. Addressable内存释放代码

    Unity Addressable内存管理_凌志·C的博客-CSDN博客_addressables 内存管理 using System.Collections; using System.Collec ...

  4. Unity开发者的C#内存管理

    很多游戏时常崩溃,大多数情况下都是内存泄露导致的.这系列文章详细讲解了内存泄露的原因,如何找到泄露,又如何规避. 我要在开始这个帖子之前忏悔一下.虽然一直作为一个C / C++开发者,但是很长一段时间 ...

  5. Unity开发者的C#内存管理(中篇)

    第一篇介绍了在 .NET/Mono 和Unity里内存管理的基础,并且提供了一些避免不必要的堆分配的建议.第三篇会深入到对象池.所有的都主要是面向中级的C#开发者. 我们现在来看看两种发现项目中不想要 ...

  6. 【Unity】Unity内存管理与优化(一)内存域、堆栈、垃圾回收、内存泄漏、内存碎片

    文章目录 Unity内存 内存域 - 托管域 - 本地域 - 外部库 - 跨桥操作 堆和栈 - 栈 - 堆 - 堆栈的使用 垃圾回收 - Mono内存分配过程 - 内存泄漏 - 内存碎片 - 运行时垃 ...

  7. Unity内存管理的原理

    [前言] 当我们谈及Unity内存管理时,我们更多的是在说手游项目上如何更好的去管理内存,如果是在端游项目上,没有那么多讲究,内存随便用. [为什么手机上内存不够用] CPU读写速度远快于内存的速度, ...

  8. Unity游戏开发中的内存管理_资料

    http://mp.weixin.qq.com/mp/homepage?__biz=MzAwMTUzOTczNQ==&hid=6&sn=44228b7260d7a5a3287a4499 ...

  9. Unity加载机制及内存管理

    原文地址: http://game.ceeger.com/forum/read.php?tid=4394 作者写的非常精彩~ 一 Unity里有两种动态加载机制 1,Resources.Load:从一 ...

最新文章

  1. ASP.NET入门五步详解
  2. pytorch 构建神经网络模型总结
  3. 关于在unity中动态获取字符串后在InputField上进行判断的BUG
  4. 【EPS精品教程】基于DOM和DSM创建垂直模型、加载垂直模型
  5. ApacheCN 捐赠名单 2019
  6. 一个简单的微服务项目带你上手spring cloud 全家桶
  7. mysql like 4种优化_mysql like优化_超级优化 清木桥
  8. 仿京东商城登录页面html
  9. 坦然面对:应对前端疲劳
  10. 前端JSON格式化显示
  11. UCOSIII总结------消息队列(6)
  12. h5新语义化标签(重要)
  13. PS调色精灵ps插件
  14. 激活黑群晖Synology Active Backup for Business,黑群晖系统备份软件激活,亲测有效
  15. Ad hoc Test
  16. 对话bot语音输入交互竞品调研
  17. Qt Quick - Slider
  18. 计算机主板 大 小,电脑主板选大的还是小的比较好?
  19. xswl,这个全程搞笑的综艺节目终于开播了(披荆斩棘的哥哥)
  20. 程序员是不是人均黑客?

热门文章

  1. 定位跟踪器物联网卡应用场景
  2. android讲义doc,OPhone、android讲义.doc
  3. 海龟程序如何在python中打开_【Python】之海龟图形化程序
  4. flack框架..学习中
  5. gfs文件存储服务器,GFS分布式文件存储系统(理论)
  6. Deepin20Beta启用网卡远程开机/唤醒功能Wake-on-LAN(WOL)并保持开启状态
  7. python-正则表达式之findall的用法
  8. sql根据条件删除重复数据保留一条
  9. mysql splunk_SPLUNK 安装配置及常用语法
  10. 一个能看懂的Redis思维导图