Memory leak problem and countermeasures when using models from AssetBundle

[Last updated : 10/21/2020]

Loading and unloading Prefab from AssetBundle for models using clipping may cause memory leaks depending on how CubismMaskTexture is handled.

This section describes the causes and reasons for the lack of support, as well as countermeasures to address the issue.

 

Summary

To handle models with clipping set in Unity, use CubismMaskController.
CubismMaskController.MaskTexture (instance of CubismMaskTexture), if not set, refers to GlobalMaskTexture in the application at initialization.
However, depending on the project specifications, an instance of CubismMaskTexture may be included in the AssetBundle instead of on the application side.
In this case, loading and unloading models from AssetBundle may cause memory leaks.

The cause of memory leaks is that the RenderTexture inside CubismMaskTexture remains after it is generated.
There are two ways to deal with this problem, depending on how CubismMaskTexture is used.

CASE 1: If you are using one CubismMaskTexture for all models
1-1. Delete EditorGUILayout.ObjectField in CustomMaskControllerInspector.cs
1-2. Change _maskTexture serialized in CubismMaskController.cs to a non-serialized process
1-3. Rebuild AssetBundle

case 2: If you have an instance of CubismMaskTexture for each model
2-1. Create a method to delete _renderTexture in CubismMasktexture.cs
2-2. Call the method created in 2-1 at the timing of destroying the model
2-3. Re-create AssetBundle

Either of the above measures will eliminate the memory leak.

 

Background/Causes

After making an AssetBundle of a Live2D model with clipping set, loading and unloading the model from the AssetBundle causes a memory leak.

The reason is that a RenderTexture for the mask is generated each time the model is loaded, and the RenderTexture remains even if the model is deleted.
Objects set in a component are made into an AssetBundle with a copy of the object, not a reference to the object.
As a result, if a model is generated through AssetBundle conversion and CubismMaskController.MaskTexture is set to GlobalMaskTexture, an instance of CubismMaskTexture, a copy of GlobalMaskTexture will be generated and a RenderTexture created at the same time each time the model is loaded.
However, even if the model is deleted, the RenderTexture remains undeleted. This results in memory leaks.

The fix for this bug has not been reflected in the Cubism SDK for the following three reasons.

  1. Because the method of handling RenderTexture for masks differs depending on how it is handled
  2. Because CubismComponents, which focuses on clarity and structural simplicity, becomes more complex
  3. Because there is no problem if you do not use AssetBundle

 

Counter-measure

Points to note in countermeasures

This section presents two measures.

As a reminder, the two measures are independent measures, so do not use both measures in one project at the same time.

Countermeasures vary depending on how CubismMaskTexture is used. There are two cases: when only one CubismMaskTexture is used, and when a CubismMaskTexture is instantiated and used for each model.
Here is a description of one measure for each of the two uses.

 

Case 1: To display a model using a single CubismMaskTexture

If you are using a single CubismMaskTexture to display a model, take this measure.

First, delete the EditorGUILayout.ObjectField contained within the CustomMaskControllerInspector.cs.

 

Next, change the _maskTexture serialized in CubismMaskController.cs to a non-serialized process.

 

This has been taken care of.
After this, re-create the AssetBundle.

 

case 2: If you have an instance of CubismMaskTexture for each model

If you have instances of CubismMaskTexture for each model, here are the measures to take.

First, create a public method in CubismMaskTexture.cs to Destroy _randerTexture.
The following is an example code.

 

The aforementioned method is called when the model is to be destroyed.
As a result, the RenderTexture can be deleted as well as the model.

After the above measures have been taken, recreate the AssetBundle.

 

© 2010 - 2022 Live2D Inc.