Impact on App Memory
The impact of hybridclr on the App runtime memory is mainly composed of the following parts:
- Dynamic heap memory
- (Increase) Maintain the memory occupied by the bridge function mapping
- (Increase) Interpreter thread data stack and frame stack memory
- (Increase) Memory occupied by instruction optimization module (only available in commercial version)
- (Increase) Additional metadata memory usage related to DHE (only available on Ultimate Edition)
- (Reduce) Optimize libil2cpp metadata memory management (only available on commercial versions). Significantly reduced metadata memory overhead
- Static Code Segment Memory
- (Added) The bridge function MehtodBridge.cpp increases the binary code size after compilation
- (Increased) Additional code bloat introduced by DHE code injection resulting in increased binary size (only available on Ultimate builds)
- (Reduce) Reduce binary code size by converting AOT assemblies to normal interpreted assemblies (excluding DHE assemblies, because DHE assemblies also need to be compiled into AOT)
Although the increased static code segment memory size will be displayed in the total memory of the App, it does not represent the actual memory usage of the code. Static Code segment codes are loaded on demand. To see the actual memory usage, you need to check the data of Actual Physical Memory Occupied (RSS)
.
We built a test project to test the actual impact of hybridclr on the package body.
test
We tested the memory usage of the Android Armv8 platform apk built in Unity 2021.
The AOT part of the test project fully includes the following frameworks and libraries:
- mscorlib, System, System.Core
- UnityEngine.dll, UnityEngine.CoreModule.dll, UnityEngine.UI.dll, UnityEngine.PhysicsModule.dll
- GameFramework framework
- HybridCLR.Runtime.dll
- Luban
- UniTask
- YooAsset
We counted the total size of the AOT module dll after building the apk: a total of 12.0M.
The hot update code of the test project consists of the following parts:
- Unit test engineering code
- Configuration code generated by Luban
The compiled HotUpdate.dll is 1216k.
The size of the bridge function MethodBridge.cpp is 15088K.
We compared the memory usage of the following situations:
- NotHybridCLR-NotHotUpdateCode: HybridCLR is not connected, and HotUpdate code is not included
- NotHybridCLR-HotUpdateCode is not connected to HybridCLR, including HotUpdate code
- HybridCLR Community Edition-NotHotUpdateCode connects to the HybridCLR Community Edition, does not contain HotUpdate code, and generates bridge function files normally
- HybridCLR Community Edition-HotUpdateCode is connected to the HybridCLR Community Edition, including HotUpdate code, and generates bridge function files normally
- HybridCLR Professional Edition-NotHotUpdateCode Access to HybridCLR Professional Edition, does not contain HotUpdate code, and generates bridge function files normally
- HybridCLR Professional Edition-HotUpdateCode is connected to HybridCLR Professional Edition, including HotUpdate code, and generates bridge function files normally
- HybridCLR Ultimate Edition-NotHotUpdateCode Access to HybridCLR Ultimate Edition, does not contain HotUpdate code, and generates bridge functions normally
- HybridCLR Ultimate Edition - HotUpdateCode-LoadOriginalDifferentialHybridAssembly Access to HybridCLR Ultimate Edition, including HotUpdate code, normal generation of bridge functions, HotUpdate assembly is not changed, use RuntimeApi::LoadOriginalDifferentialHybridAssembly to load HotUpdate
- HybridCLR Ultimate Edition - HotUpdateCode - LoadDifferentialHybridAssembly Access to HybridCLR Ultimate Edition, including HotUpdate code, normal generation of bridge functions, HotUpdate assembly is not changed, use RuntimeApi::LoadDifferentialHybridAssembly to load HotUpdate
The test results are as follows:
Build method | App heap memory (K) |
---|---|
NotHybridCLR-NotHotUpdateCode | 51343 |
NotHybridCLR-HotUpdateCode | 59400 |
HybridCLR Community Edition-NotHotUpdateCode | 53592 |
HybridCLR Community Edition-HotUpdateCode | 65695 |
HybridCLR Professional Edition-NotHotUpdateCode | 50380 |
HybridCLR Professional Edition-HotUpdateCode | 62235 |
HybridCLR Ultimate-NotHotUpdateCode | 52531 |
HybridCLR Ultimate Edition-HotUpdateCode-LoadOriginalDifferentialHybridAssembly | 61276 |
HybridCLR Ultimate Edition-HotUpdateCode-LoadDifferentialHybridAssembly | 65655 |
Based on the above test items, we can draw the following conclusions:
- (Increase) The bridge function occupies about
{bridge function file MethodBridge.cpp file size} * 0.1
size of heap memory - (Increase) Each thread executing the hot update code will occupy about 1.2M memory
- (Added) instruction optimization module (only available in commercial version) takes up about 700K
- (Increased) Additional metadata memory usage related to DHE (only available in Ultimate Edition). Approximately
{total size of AOT assemblies + total size of DHE assemblies} * 0.12
in memory - (Increase) The binary code size of the bridge function MehtodBridge.cpp increases after compilation. Approximately
{MethodBridge.cpp file size} * 0.3
- (ADDED) DHE (Ultimate only) Code injection introduces additional code which increases binary size. Approximately
{DHE assembly size} * 0.86
- (Reduce) Optimize libil2cpp metadata memory management (only available in commercial version), reducing metadata memory overhead by
10-25%
- (Reduce) Reduce binary code size by converting AOT assemblies to normal interpreted assemblies (excluding DHE assemblies, because DHE assemblies also need to be compiled into AOT). Approximately
{hot update assembly size} * 5.2
size
Summarize
Community Edition
- The newly added heap memory is approximately
{MethodBridge.cpp size} * 0.1
+1.2M * {number of threads that have executed interpreted code}
+{hot update assembly size} * 2.2
- Increase Code segment memory is about
{MethodBridge.cpp size} * 0.3
-{Hot update assembly size} * 5.2
Generally speaking, the binary code will be reduced after accessing the community version, that is, the added memory of code segment
is generally a negative value.
Professional Edition
- The newly added heap memory is approximately
{MethodBridge.cpp size} * 0.1
+ 0.7M (instruction optimization module memory) +1.2M * {number of threads that have executed interpreted code}
+{hot update assembly size} * 1.6
-{all assembly sizes} * 0.2
- Increase Code segment memory is about
{MethodBridge.cpp size} * 0.3
-{Hot update assembly size} * 5.2
Generally speaking, the binary code will be reduced after accessing the professional version, that is, the added memory of code segment
is generally a negative value.
Ultimate Edition
- The newly added heap memory is approximately
{MethodBridge.cpp size} * 0.1
+ 0.7M (instruction optimization module memory) +1.2M * {number of threads that have executed interpreted code}
+{hot update assembly size} * 3
+{total size of AOT assemblies + total size of DHE assemblies} * 0.12
-{size of all assemblies} * 0.2
- Increase Code segment memory to approximately
{DHE assembly size} * 0.86
+{MethodBridge.cpp size} * 0.3
Since the sample project is small, the test results may not be consistent with the actual project. {hot update assembly size} * 3
This part of memory is obviously overestimated. Please refer to the actual project.