Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
4
Help us understand the problem. What is going on with this article?
@majimeneko

Managed Strippingしてみた

More than 1 year has passed since last update.

はじめに

Unity 2018.3での更新内容の一つにマネージドコードストリッピング機能の標準化があります。
今後、利用する機会が増えるかもしれないため、マネージドコードストリッピングを試したいと思いました。
ソースコードの削除に伴う問題などもちらほらと聞いたりするため、そちらも試してみたいと思います。

使用したバージョン

Unity 2018.3.0b11

Managed Stripping Levelについて

新しくなったProject Settingsから Managed Stripping Level を切り替えることができます。

project-settings-01.jpg

Managed Stripping Levelのそれぞれのレベルは以下のようになっています。

Managed Stripping Level 概要
Disable コードの削除を行わない。
Low 到達できないコードを削除する。
Medium Lowよりもさらにコードを削減する。
同じリフレクションコードでも同じ動作をしない可能性がある。
カスタムlink.xmlを用意することで削除対象のコードを含めることができる。
High Mediumよりもさらにコードを削除する。
いくつかのメソッドのデバッグコードが動作しない可能性がある。
同じリフレクションコードでも同じ動作をしない可能性がある。
カスタムlink.xmlを用意することで削除対象のコードを含めることができる。

正確な内容は以下のUnityのドキュメントをご参照ください。
Unity - Scripting API: ManagedStrippingLevel

サイズの変化

新規作成したプロジェクトをそれぞれの設定でAPKを作成し、そのサイズを比較してみました。
Scripting BackendはMonoでAPKを作成しています。

Managed Stripping Level サイズ DLLの個数
Disable 26,394 KB 89
Low 21,427 KB 35
Medium 21,215 KB 32
High 21,145 KB 29

DisableからLowになったときが一番変化が大きい状態となっていました。
DLLの個数が大きく減っていますが、DLL自体の大きさも大きく変わっているものがありました。

コードの変化

簡単なリフレクションを利用する処理を書いてみて、そのコードがどのように変化するのか比較してみました。
用意したコードは以下のようなものです。

CallFunction.cs
using UnityEngine;

public class CallFunction
{
    public CallFunction()
    {
        Debug.Log("Call Constructor");
    }

    public void Func()
    {
        Debug.Log("Call Func");
    }
}
CallerBehaviour.cs
using System;
using UnityEngine;

public class CallerBehaviour : MonoBehaviour
{
    private void Start()
    {
        var t = Type.GetType("CallFunction");
        var o = Activator.CreateInstance(t);
        t.GetMethod("Func").Invoke(o, new object[0]);
    }
}

CallFunctionのコンストラクタとFuncメソッドはどこからも直接的に利用されておらず、リフレクションによって間接的に利用されています。
実行するとConsoleタブにログが表示されます。

console01.jpg

作成したAPKを解凍し、内部に含まれている Assembly-CSharp.dll をilspyなどでデコンパイルして中身を見てみます。
Medium以降のDLLでは、CallFunctionの中身が削除されてしまっています。

Managed Stripping Level DLLの中身
Disable ilspy-none.jpg
Low ilspy-low.jpg
Medium ilspy-medium.jpg
High ilspy-high.jpg

Assets以下に下記のようなlink.xmlを作成すると削除されてしまっていたコードを残すことができます。

link.xml
<linker>
    <assembly fullname="Assembly-CSharp">
        <type fullname="CallFunction" preserve="all"/>
    </assembly>
</linker>

他にも残したいコードやDLLの内容がある場合は、link.xmlに記載していきます。

まとめ

  • Managed Stripping Levelは、Player Settingsから簡単に設定できる。
  • Lowの段階でも大きくアプリサイズが変わっていた。(ほぼ新規作成の状態のプロジェクトの場合。)
  • Medium以上の設定にすると直接呼び出されていないメソッドなども削除される。
  • link.xmlを作成し、記述することで削除対象になっているメソッドなどを残しておくことができる。

参考URL

Unity - Scripting API: ManagedStrippingLevel

IL2CPP を使ったマネージバイトコードストリップ - Unity マニュアル

4
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
4
Help us understand the problem. What is going on with this article?