バケットアロケーターは、小さな割り当てを行う高速なロックフリーアロケーターです。通常、バケットアロケーターは、ヒープアロケーターに行く前に、小さな割り当てを高速化するための第一ステップとして使用されます。
このアロケーターは、割り当て用にメモリのブロックを予約します。各ブロックが 16 KB の サブセクション に分割されます。これは設定調整可能ではなく、ユーザーインターフェースにも表示されません。各サブセクションが 割り当て (アロケーション) に分割されます。割り当てのサイズは、設定された固定サイズの倍数で、粒度 と呼ばれます。
The following example configuration demonstrates the process of reserving blocks for allocations:
この設定では、合計 ブロック サイズ (Bucket Allocator Block Size) が 4 MB で、割り当ての粒度 (Bucket Allocator Granularity) が 16 B です。最初の割り当てが 16 B、2番目が 32 B (2*16)、次が 48 B、64 B、80 B、96 B、112 B、128 B で、合計 8 つのバケット (Bucket Allocator BucketCount) になります。
各サブセクションが、それぞれ異なる数のバケットを含みます。サブセクションのバケット数を計算するには、サブセクションのサイズ (16 KB) を粒度のサイズで割ります。例えば、次のようになります。
Bucket allocators produce different usage reports for a development build and a release build because in a development build each allocation has an additional 40B header. The following diagram demonstrates the difference between development and release builds for 16B and 64B allocations:
The header is the reason the allocator reports being full after allocating only 2MB of its 4MB:
[ALLOC_BUCKET]
Large Block size 4.0 MB
Used Block count 1
Peak Allocated bytes 2.0 MB
Failed Allocations. Bucket layout:
16B: 64 Subsections = 18724 buckets. Failed count: 3889
32B: 17 Subsections = 3868 buckets. Failed count: 169583
48B: 31 Subsections = 5771 buckets. Failed count: 39674
64B: 28 Subsections = 4411 buckets. Failed count: 9981
80B: 17 Subsections = 2321 buckets. Failed count: 14299
96B: 6 Subsections = 722 buckets. Failed count: 9384
112B: 44 Subsections = 4742 buckets. Failed count: 5909
128B: 49 Subsections = 4778 buckets. Failed count: 8715
同じプロジェクトのリリースビルドでは、アロケーターのブロックサイズで十分です。
[ALLOC_BUCKET]
Large Block size 4.0 MB
Used Block count 1
Peak Allocated bytes 3.3 MB
バケットアロケーターが一杯になると、割り当てが他のアロケーターにフォールバックします。使用量レポートには、失敗した割り当ての数も含めた使用統計が表示されます。直線的に増加する失敗カウントがレポートに表示される場合、ロードではなくフレームの計算時に割り当ての失敗が発生している可能性が高いことを意味します。フォールバック割り当ては、シーンのロードでは問題ありませんが、フレーム計算時に発生するとパフォーマンスに影響を与える可能性があります。
To prevent these fallback allocations, increase the block size, and limit the new block size to match the frames’ peak usage, rather than the scene load peak usage. This prevents the block from becoming so large that it reserves a lot of memory which is then not available at runtime.
Tip: The Profiler allocators share an instance of a bucket allocator. You can customize this shared instance in the Profiler Shared Bucket Allocator.