Unity Memory Request and release

Source: Internet
Author: User

Transferred from: http://www.jianshu.com/p/b37ee8cea04c

1. Resource types

Gameobject, Transform, Mesh, Texture, Material, Shader, script and various other assets.

2. How resources are created
    • Static Reference, add a public gameobject variable in the script, drag a prefab to the variable in the Inspector panel, and then instantiate where the reference is needed;
    • Resource.load, the resource needs to be placed in the assets/resources directory;
    • assetbundle.load, after Load instantiate. 3. Resource Destruction Mode
    • Gameobject.destroy (gameobject), destroying the object,
    • Assetbundle.unload (false), releasing the Assetbundle file memory image, The assets object created by load is not destroyed;
    • Assetbundle.unload (True), releasing the Assetbundle file memory image while destroying all the assets memory images that have been load;
    • Resources.unloadasset (object), releasing the loaded asset object,
    • resources.unloadunusedassets, releasing all asset objects that are not referenced. 4. The life cycle experiment has created a simple scenario in which an empty gameobject is created, a script is hung on it, and a awake function is created to create resources in the Coroutine function. The prefab created in the
      experiment was a tank car, adding about 3M of scene memory in the scene and creating a Assetbundle resource for assetbundle use. 1. Resources.load mode to load a prefab, and then instantiate Gameobject code as follows:
   IEnumerator LoadResources()    {        // 清除干净以免影响测试结果        Resources.UnloadUnusedAssets();        // 等待5秒以看到效果        yield return new WaitForSeconds(5.0f);        // 通过Resources.Load加载一个资源        GameObject tank = Resources.Load("Role/Tank") as GameObject;        yield return new WaitForSeconds(0.5f);        // Instantiate一个资源出来        GameObject tankInst = GameObject.Instantiate(tank, Vector3.zero, Quaternion.identity) as GameObject;        yield return new WaitForSeconds(0.5f);        // Destroy一个资源        GameObject.Destroy(tankInst);        yield return new WaitForSeconds(0.5f);        //释放无用资源        tank = null;        Resources.UnloadUnusedAssets();        yield return new WaitForSeconds(0.5f);    }

The results of the implementation are as follows:

Here are the statistical results:

Total
Data Description Memory Texture Mesh Material gameobjects Objects in SceneObjects
Initial 72.8M 1271/8.0m 35/223.0k 25/10.2k 7 211 2187
Resources.load 72.8M 1271/8.0m 36/0.8m 25/10.2k 7 211 2280
Instantiate 75.3M 1272/9.3m 36/0.8m 26/10.7k 52 303 2375
Destroy 74.7M 1272/9.3m 36/0.8m 26/10.7k 7 211 2283
Resources.unloadunusedassets 72.3M 1271/8.0m 35/223.0k 25/10.2k 7 211 2187

From here we draw the following conclusions:

    • Resouces.load A prefab is a relatively lightweight operation relative to instantiate a resource, resources.load loading a prefab consumes almost no memory, while instantiate consumes 2.5M of resource space. Resources.load increases the number of mesh and total objects, while instantiate increases the number of gameobjects,objects in scene and Total Objects;
    • Destroy after a gameobject, memory is reduced, but less, in this case, the material and texture in this example are reduced by 0.6m;instantiate and destroy, and are not restored to continue the instantiate later.

If Resources.unloadunusedassets is not called, the result is as follows:

The statistical results are as follows:

Total
Data Description Memory Texture Mesh Material gameobjects Objects in SceneObjects
Initial 58.9M 1258/7.5m 34/219.2k 22/9.0k 7 117 2078
Resources.load 60.0M 1258/7.5m 35/0.8m 22/9.0k 7 117 2171
Instantiate 62.5M 1259/8.9m 36/0.8m 23/9.5k 52 209 2256
Destroy 61.8M 1259/8.9m 35/0.8m 23/9.5k 7 117 2174

The following conclusions are drawn:
If you do not perform resources.unloadunusedassets manually, redundant mesh,material and objects are not actively freed.

2. Load a prefab in a assetbundle.load manner, and then instantiate a Gameobject

The code is as follows:

 IEnumerator LoadAssets(string path)    {        // 清除干净以免影响测试结果        Resources.UnloadUnusedAssets();        // 等待5秒以看到效果        yield return new WaitForSeconds(5.0f);        // 创建一个WWW类        WWW bundle = new WWW(path);        yield return bundle;        yield return new WaitForSeconds(0.5f);        // AssetBundle.Load一个资源        Object  obj =  bundle.assetBundle.Load("tank");        yield return new WaitForSeconds(0.5f);        // Instantiate一个资源出来        GameObject tankInst = Instantiate(obj) as GameObject;        yield return new WaitForSeconds(0.5f);        // Destroy一个资源        GameObject.Destroy(tankInst);        yield return new WaitForSeconds(0.5f);        // Unload Resources        bundle.assetBundle.Unload(false);        yield return new WaitForSeconds(0.5f);        // 释放无用资源        //obj = null;        //Resources.UnloadUnusedAssets();        yield return new WaitForSeconds(0.5f);    }

The results of the implementation are as follows:

The statistical results are as follows:

Total
Data Description Memory Texture Mesh Material gameobjects Objects in SceneObjects
Initial 59.9M 1267/7.8m 35/223.0k 25/10.2k 7 127 2099
New WWW 62.0M 1267/7.8m 35/223.0k 25/10.2k 7 127 2099
Assetbundle.load 64.5M 1268/9.2m 36/0.8m 26/10.5k 7 127 2196
Instantiate 65.6M 1268/9.2m 36/0.8m 26/10.7k 52 219 2288
Destroy 63.9M 1268/9.2m 36/0.8m 26/10.7k 7 127 2196
Assetbundle.unload 63.7M 1268/9.2m 36/0.8m 26/10.7k 7 127 2196
Resources.unloadunusedassets 61.8M 1267/7.8m 35/223.0k 25/10.2k 7 127 2099

The following conclusions are drawn:
The mesh,texture and material are loaded automatically when a resource is loaded via the WWW load assetbundle, and loading with the Resouces.load mode loads only the mesh information. As a result, the memory consumption of instantiate a resource is smaller after loading by assetbundle mode, in this case Assetbundle.load adds 2.5M of memory, and instantiate adds 1.1M of memory. The memory increment of instantiate is much smaller compared to resources.load.

3. Instantiate a resource by means of a static binding

The code is as follows:

    IEnumerator InstResources()    {        Resources.UnloadUnusedAssets();        yield return new WaitForSeconds(5.0f);        GameObject inst = GameObject.Instantiate(tank, Vector3.zero, Quaternion.identity) as GameObject;        yield return new WaitForSeconds(1f);        GameObject.Destroy(inst);        yield return new WaitForSeconds(1f);        //释放无用资源        tank = null;        Resources.UnloadUnusedAssets();        yield return new WaitForSeconds(1f);    }

The results of the implementation are as follows:

The statistical results are as follows:

Total
Data Description Memory Texture Mesh Material gameobjects Objects in SceneObjects
Initial 62.0M 1268/7.9m 36/0.8m 25/10.2k 7 134 2202
Instantiate 64.4M 1269/9.2m 36/0.8m 26/10.7k 8 137 2207
Destroy 64.0M 1269/9.2m 36/0.8m 26/10.7k 7 134 2204
Unloadunused Resources 62.3M 1268/7.9m 35/226.3k 25/10.2k 7 134 2107

The following conclusions are drawn:
By statically binding the load order of various resources is the same as Resources.load, when a gameobject is created, its component statically bound Gameobject only loads the mesh information, only if the Gameobject Texture and material information will not be loaded until instantiate is released.

Theory Chapter

The process of loading resources can be divided into two phases, the first phase is to load various resources using Resources.load or assetbundle.load, and the second phase is to clone a new gameobject using Gameobject.instantiate.
The types of load resources include Gameobject, Transform, Mesh, Texture, Material, shader, and script. But there is a difference between resources.load and assetbundle.load.
When using Resources.load, the corresponding asset object was not created until the first instantiate, and it was not actually read until the first instantiate to create these assets. Its purpose is to implement a way of using OnDemand to create these resources when the resource is actually used.
When using the Assetbundle.load method, the resource files are read directly to create these assets, so the first instantiate will be relatively small.
These differences can help us explain why there is a noticeable lag when launching the first bullet.

Then we'll look at the instantiate process. The process of instantiate is a process of combining clone (copy) and reference to assets, and the process of cloning requires the memory to store its own data, whereas the process of referencing only needs to direct a simple pointer to a resource that has already been load. For example, transform is out of clone, texture and Terraindata are copied by reference, and mesh,material,physicalmaterial and script are both clone and reference. In script, for example, the script is divided into code snippets and data segments, all the code that needs to use the script is the same, and everyone's data is different, so you need to use clone for the data segment, and the code snippet needs to be gameobject in the way it is referenced.
Therefore the load operation actually load some data source, used to create a new object is clone or referenced.

Then is the process of destroying resources. When destory a gameobject or other instance, it releases only those clone assets from the instance, and does not release those referenced assets, because destroy does not know if anyone else is referencing the assets. When no objects in the scene refer to these assets, they become unusedassets, which can be released by Resources.unloadunusedassets. Assetbundle.unload (false) does not work because it frees only the memory image of the file, does not release the resource, and Assetbunde.unload (true) is not possible because it is a release of violence, and there may be other objects referencing the assets, Brute force release can cause program errors.
It is also important to note that all memory objects are automatically destroyed when the system loads a new scene, including resources.load loaded assets, statically bound assets, Assetbundle.load loaded resources and instantiate instantiated objects. However, Assetbundle.load's own file memory image (used to create various asset) is not automatically destroyed, which must be actively destroyed using Assetbundle.unload (false). The recommended practice is to call Assetbunble.unload (false) to destroy the file memory image immediately after the resource is loaded.
Can help understand the relationship between asset and Gameobject in memory.

Concluding article
    • In order to avoid the phenomenon of the first instantiate, it is recommended to use Assetbundle.load instead of resources.load to load the resources in a way;
    • Immediately after the resource is loaded, call Assetbunble.unload (false) to release the file memory image;
    • Unity itself does not provide a good memory application and release management mechanism, destroy a gameobject will immediately release memory instead of internal cache, so the application of frequently used objects such as NPC,FX, such as the object pool management is necessary to reduce the number of memory applications;
    • When to Resources.unloadunusedassets is an issue that needs to be discussed.
REF:

http://game.ceeger.com/forum/read.php?tid=4394
http://game.ceeger.com/forum/read.php?tid=4466

Unity Memory Request and release

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.