Unity full understanding of load and memory management

Source: Internet
Author: User
Tags shallow copy

recently has been entangled with these content, the experience and share with you:

There are two dynamic loading mechanisms in unity: one is resources.load, one is through assetbundle, in fact, I understand that there is no difference in nature. Resources.load is from a default into the package Assetbundle loading resources, and general Assetbundle files need you to create, run-time dynamic loading, you can specify the path and source.

in fact, all the static objects in the scene also have such a loading process, but unity backstage for you to automatically complete.

elaborate on the concept of detail:
Assetbundle Run-time loading:
CreateFromFile from files (Note that this method can only be used for standalone programs) This is the fastest way to load
can also come from memory, with Createfrommemory (byte[]), this byte[] can be from file read buffer, www download or other possible way.
in fact, www assetbundle is the internal data read after the automatic creation of a assetbundle just
after create, is equal to the hard disk or the network of a file read into an area of memory, this time is just a assetbundle memory image data block, there is no concept of assets.
Assets Loading:
with Assetbundle.load (same resources.load) This will read and create a asset object from the Assetbundle memory image, and the asset object will also be allocated with the corresponding memory for storage (deserialization)
asynchronous read with Assetbundle.loadasync
You can also read multiple Assetbundle.loadall
release of Assetbundle:
Assetbundle.unload (flase) is a memory image that releases Assetbundle files and does not contain asset memory objects created by load.
Assetbundle.unload (True) is to release that assetbundle file memory image and destroy all asset memory objects created with load.

a prefab from the assetbundle. Inside may include: gameobject transform mesh texture material shader script and various other assets.
you instantiate a prefab, is a assets clone (copy) + reference combination of the process, Gameobject transform is clone is a new generation. Other Mesh/texture/material/shader, some of which are purely reference relationships, include:texture and terraindata, as well as references and replication, including: Mesh/material/physicmaterial. The referenced asset object is not copied, just a simple pointer to the asset object that has already been load. this vague reference-plus-clone mix is probably the main reason to confuse most people.
specifically to mention is a special thing:Script Asset , it seems strange that every script in unity is a closed class definition and does not write the calling code, and the definition script of the light class does not work. In fact, the unity engine is the calling code, clone a script asset equals the new class instance,The instance will not complete the work. By adding a script Assets to the object by addcomponent, it completes theThe execution of the script class instance into the call chain of the unity main thread, OnUpdate OnStart in the class instance, will be executed. More than one object hangs the same script, in fact, it is to hang the multiple instances of the script class on more than one object, so it is understandable. In the process of new class, the data area is copied, and the code area is shared, which is a special copy + reference relationship.
You can instantiate a similar prefab, or this set of Mesh/texture/material/shader ..., this time there will be a new gameobject, etc., but will not create a new reference object such as texture.
so the assets that you load is actually a data source that is used to generate new objects or to be referenced, and the resulting process might be a copy (clone) or a reference (pointer)
When you destroy an instance, just release those clone objects and do not release the data source object that references the object and clone, destroy does not know if there are any other objects that reference them.
wait until there is no game scene object after the use of these assets, these assets become no reference to the free data block, is unusedassets, this time can be released through the Resources.unloadunusedassets, Destroy cannot complete this task, Assetbundle.unload (false), Assetbundle.unload (true) can but is not safe unless you know that no object is using these assets.
with a picture to deepen understanding:


Although called asset, the copy and the reference are not the same, this is masked by unity's dark technical details, need to understand.

About memory Management
according to the traditional programming thinking, the best way is to maintain all the objects, with a queue to save all the object, not when the destory, the unload's own processing.
but this is a bit unnecessary and cumbersome under the C #. NET Framework.
On the safe side, you can manage that .

when created:
first build a assetbundle, whether from www or file or memory
load the required asset with Assetbundle.load
immediately after loading, Assetbundle.unload (false) releases the memory image of the Assetbundle file itself, but does not destroy the loaded asset object. (so you don't have to save the Assetbundle reference and you can immediately release a portion of the memory) 
when released:
If there are instantiate objects, destroy them with destroy.
call Resources.unloadunusedassets at the appropriate place to release the asset that have not been referenced.
If you need to free memory immediately plus gc.collect (), memory may not be released immediately, sometimes causing excessive memory consumption and throwing an exception.
This ensures that the memory is always released in a timely manner, taking the least amount. There is also no need to reference each loaded object.

This is not the only way, of course, as long as you follow the principle of loading and releasing, anything can be done.

when the system loads a new scene, all the memory objects are automatically destroyed, including the objects you loaded with Assetbundle.load and the Instaniate clones. But it does not include the memory image of the Assetbundle file itself, which must be freed with unload, and in. NET terms, this data cache is unmanaged.


summarize the various loading and initialization uses:
Assetbundle.createfrom ..... : Create a Assetbundle memory image and note that the same Assetbundle file cannot be used again until it is unload
WWW.AssetBundle: Ditto, of course, the first new one and then yield return before you can use
assetbundle.load (name): reads a asset of the specified name from the Assetbundle and generates a asset memory object, if multiple Load objects of the same name are returned, except for the first time, only the asset objects that have been generated. That is, multiple load a asset does not generate more than one copy (singleton) .
resources.load (path;name): Ditto, just load from the default location.
instantiate (object): Clone a complete structure of an object, including all its component and sub-objects (see official documentation), shallow copy, and does not copy all reference types. There is a special usage, although rarely used, in fact, can be used instantiate to complete the copy of a reference type of asset, such as texture, to copy the texture must be type set to read/write able.

summarize the various releases
Destroy: Used primarily for destroying cloned objects or for static objects within a scene, and does not automatically release all references to the object. Although it can also be used for asset, the concept is not as careful if the asset object that is used to destroy the load from the file destroys the corresponding resource file! However, if the destroyed asset is copy or dynamically generated with a script, only the memory object will be destroyed.
Assetbundle.unload (FALSE): Release Assetbundle file memory image
Assetbundle.unload (TRUE): Releases Assetbundle file memory image while destroying all assets memory objects that have already been load
Reources.unloadasset (object): explicitly releasing loaded asset objects, only unloading asset objects loaded by the disk file
resources.unloadunusedassets: Used to release all asset objects that are not referenced
GC. Collect () force garbage collector to release memory immediately Unity's GC function is not good, and when you're not sure, force a call.

before 3.5.2, it was like unity couldn't explicitly release asset. 


give two examples to help understand
Example 1:
a common error:you Load a prefab from a assetbundle and clone it: obj = Instantiate (assetbundle1.load (' Myprefab ');
This prefab, like a NPC .
and then you don't need him. You used: Destroy (obj); you thought you were free.
In fact, this time just released the Clone object, all the references loaded through load, non-reference assets objects all lie quietly in memory.
This situation should be used after destroy: Assetbundle1.unload (True), completely released cleanly.
if the AssetBundle1 is inconvenient unload to be read repeatedly, it can be used after destroy: Resources.unloadunusedassets () destroys all asset associated with the NPC.
of course, if the NPC is to be frequently created and destroyed, then those assets should be kept in memory to speed up the gaming experience.
This can explain another topic that was previously mentioned: why instantiate a prefab when first time, because before you first instantiate, The corresponding asset object has not been created, to load the system built-in assetbundle and create assets, the first time after you destroy, but prefab objects are still in memory, so soon.


Example 2:
reads a 1.unity3d file from disk into memory and builds a AssetBundle1 object 
Assetbundle AssetBundle1 = Assetbundle.createfromfile ("1.unity3d");
Read and create a texture Asset from the AssetBundle1 and point the obj1 main map to it
obj1.renderer.material.mainTexture = Assetbundle1.load ("Wall") as Texture;
The Obj2 's main map also points to the same texture Asset
obj2.renderer.material.mainTexture =obj1.renderer.material.mainTexture;
texture is a reference object and will never have automatic replication (unless you really need to implement copy with your code), just create and add references
If you continue:
Assetbundle1.unload (true) that obj1 and obj2 all turned black, because the texture asset to the point was gone.
if:
Assetbundle1.unload (false) that obj1 and obj2 do not change, just the memory image of AssetBundle1 is released
Continue:
Destroy (obj1),//obj1 is released, but does not release the texture of the load just now
If this is the case:
resources.unloadunusedassets ();
there will be no memory release because texture asset is still being used by OBJ2.
if
Destroy (OBJ2)
Obj2 is released, but will not release the texture of the load just now.
continue to
resources.unloadunusedassets ();
This time the load texture asset was released because there was no reference to the
last Cg.collect ();
force immediate free memory
This can be derived from the forum of another has been raised a few questions, how to load a large number of pictures in turn show do not explode
do not consider assetbundle, directly with the WWW read the picture file is equal to directly created a texture Asset
Suppose the file is saved in a list.
tllist<string> fileList;
int n=0;
IEnumerator OnClick ()
{
www image = new www (filelist[n++]);
yield return image;
obj.maintexture = image.texture;

n = (n>=filelist.length-1)? 0:n;
resources.unloadunusedassets ();
}
This ensures that there is always only one giant texture Asset resource in memory and no code to track the last loaded texture Asset, but slower
or:
IEnumerator OnClick ()
{
www image = new www (filelist[n++]);
yield return image;
Texture tex =obj.maintexture;
obj.maintexture = image.texture;

n = (n>=filelist.length-1)? 0:n;
Resources.unloadasset (Tex);
}
it's faster to unload

Unity full understanding of load and memory management

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.