【Unity】TextComponentのバグを発見!?【Text】※7月22日更新

いきなりですが、Unityのバグを発見しました。
既知のバグならすみません。。。
※Unity2017で確認しました。
バグの内容を超簡単に説明すると
Textコンポーネントを使用していると異常終了する可能性があります。
該当のシーンに何度も遷移すると、アプリがメモリリークします。
現在わかっていること
- Unityのプロファイラーで確認してもメモリリークしているかどうか判断できませんでした(キャプチャに残しておらずすみません。後日画像貼ります)
- 端末をMacに接続して対象のアプリのメモリを確認した場合、増加が確認できました(キャプチャに残しておらずすみません。後日画像貼ります)
- 端末で実際にTextコンポーネントを使用しているシーンを何度も表示すると異常終了して落ちました(長い文字列ではなく、大量のTextコンポーネントを使用して確認)
バグの内容を少しちゃんと説明すると
最初に、オープンソースとして開示されている
UnityのTextクラスのプログラムの外部リンクを以下に貼ります。
https://bitbucket.org/Unity-Technologies/ui/src/2019.1/UnityEngine.UI/UI/Core/Text.cs
※プログラムが長いのでリンクにしています。
そして、今回悪さをしていると思われるのが
【Text】クラスで使用されている【TextGenerator】クラスです。
【TextGenerator】クラスは【IDisposable】インターフェースを実装しています。
なので、【Usingステートメント】または【Dispose()】メソッドを呼び出す必要があるのに
UnityのTextクラスではそれが行われていません。
一応、TextGeneratorとIDisposableの定義を以下に記述します。
TextGenerator
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 |
#region Assembly UnityEngine.TextRenderingModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null // UnityEngine.TextRenderingModule.dll #endregion using System; using System.Collections.Generic; using UnityEngine.Bindings; using UnityEngine.Scripting; namespace UnityEngine { // // Summary: // Class that can be used to generate text for rendering. [NativeHeaderAttribute("Modules/TextRendering/TextGenerator.h")] [UsedByNativeCodeAttribute] public sealed class TextGenerator : IDisposable { // // Summary: // Create a TextGenerator. // // Parameters: // initialCapacity: public TextGenerator(); // // Summary: // Create a TextGenerator. // // Parameters: // initialCapacity: public TextGenerator(int initialCapacity); ~TextGenerator(); // // Summary: // The number of characters that have been generated. public int characterCount { get; } // // Summary: // Number of vertices generated. public int vertexCount { get; } // // Summary: // Extents of the generated text in rect format. public Rect rectExtents { get; } // // Summary: // Information about each generated text line. public IList<UILineInfo> lines { get; } // // Summary: // Array of generated characters. public IList<UICharInfo> characters { get; } // // Summary: // Array of generated vertices. public IList<UIVertex> verts { get; } // // Summary: // The number of characters that have been generated and are included in the visible // lines. public int characterCountVisible { get; } // // Summary: // Number of text lines generated. public int lineCount { get; } // // Summary: // The size of the font that was found if using best fit mode. [NativePropertyAttribute("FontSizeFoundForBestFit", false, Bindings.TargetType.Function)] public int fontSizeUsedForBestFit { get; } public void GetCharacters(List<UICharInfo> characters); // // Summary: // Returns the current UICharInfo. // // Returns: // Character information. public UICharInfo[] GetCharactersArray(); public void GetLines(List<UILineInfo> lines); // // Summary: // Returns the current UILineInfo. // // Returns: // Line information. public UILineInfo[] GetLinesArray(); // // Summary: // Given a string and settings, returns the preferred height for a container that // would hold this text. // // Parameters: // str: // Generation text. // // settings: // Settings for generation. // // Returns: // Preferred height. public float GetPreferredHeight(string str, TextGenerationSettings settings); // // Summary: // Given a string and settings, returns the preferred width for a container that // would hold this text. // // Parameters: // str: // Generation text. // // settings: // Settings for generation. // // Returns: // Preferred width. public float GetPreferredWidth(string str, TextGenerationSettings settings); public void GetVertices(List<UIVertex> vertices); // // Summary: // Returns the current UIVertex array. // // Returns: // Vertices. public UIVertex[] GetVerticesArray(); // // Summary: // Mark the text generator as invalid. This will force a full text generation the // next time Populate is called. public void Invalidate(); // // Summary: // Will generate the vertices and other data for the given string with the given // settings. // // Parameters: // str: // String to generate. // // settings: // Settings. public bool Populate(string str, TextGenerationSettings settings); // // Summary: // Will generate the vertices and other data for the given string with the given // settings. // // Parameters: // str: // String to generate. // // settings: // Generation settings. // // context: // The object used as context of the error log message, if necessary. // // Returns: // True if the generation is a success, false otherwise. public bool PopulateWithErrors(string str, TextGenerationSettings settings, GameObject context); } } |
IDisposable
1 2 3 4 5 6 7 8 9 10 11 12 |
#region Assembly netstandard, Version=2.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51 // netstandard.dll #endregion namespace System { public interface IDisposable { void Dispose(); } } |
ちょっと疑問
TextGeneratorクラスはIDisposableインターフェースを実装しているのに、
Dispose()メソッドが実装されていないけどどういうことなんだろう・・・?
※このへんの仕様詳しい方教えていただけたら助かります。m(__)m
TextGeneratorのインスタンスからDispose()メソッド呼び出せるのかな?
と思い実際にやってみましたがダメでした。。。 な〜ぜ〜だ〜。。。泣
以下、証拠画像

何か単純な勘違いしている可能性があるので、
UnityのTextGeneratorクラスのリファレンスを見てきてみた。

Unity公式リファレンスのサンプルコードで
UsingステートメントやDispose()メソッドが記載されていないだと!?
IDisposableインターフェース実装しているんじゃなかったのか!?
念には念を、と思い
Unity公式リファレンスのTextGeneratorクラスのPublic関数一覧を見てみた。

IDisposableインターフェース実装しているのに
定義の中にもDispose()メソッドが記載されていないだと!?
いったいどういうことだってばよ!?
※このへん詳しい方おられましたら、お問い合わせから連絡いただけると泣いて喜びますm(__)m
このへんのことが今回のTextコンポーネントのメモリリークバグにつながっているのかな〜?
とりあえず、
現在開発中のアプリでTextコンポーネントを使用している方は、メモリリーク気をつけてください!
何かこの件で発展があれば改めてこの記事を更新します。
Unity公式に問い合わせてみようかなー。
7月22日更新
Unityに問い合わせた結果、Unity2017で再現することを確認していただきバグだと判断してもらえました。
また、Unity2019では再現しないようです。
投票率が高いものから修正するとのことなので、
もしよろしければ以下から、バグ修正依頼のButtonをクリックしていただけたら助かります。
Unityアカウントが必要です。
↓外部リンク(Unity)
Unity Issue Tracker
ディスカッション
コメント一覧
まだ、コメントがありません