バケットアロケーターは、小さな割り当てを実行する高速なロックフリーアロケーターです。通常、バケットアロケーターは、ヒープアロケーターに移行する前に、小さな割り当てをスピードアップするための最初のステップとして使用されます。
このアロケーターは、割り当て用にメモリブロックを予約します。各ブロックは 16KB のサブセクションに分割されます。これは設定できず、ユーザーインターフェースには表示されません。各サブセクションは割り当てに分割されます。割り当てサイズは、粒度と呼ばれる設定された固定サイズの倍数です。
以下の設定例は、割り当て用にブロックを予約するプロセスを示しています。
この設定では、合計ブロックサイズ (バケットアロケーターのブロックサイズ) は 4MB、割り当ての粒度 (バケットアロケーターの粒度) は 16B です。最初の割り当ては 16B、2 番目は 32B (2*16)、次に 48B、64B、80B、96B、112B、128B と続き、合計 8 つのバケット (バケットアロケーターのBucketCount) が割り当てられます。
各サブセクションに含まれるバケットの数は異なります。サブセクションのバケット数を計算するには、サブセクションのサイズ (16KB) を粒度サイズで除算します。 例:
バケットアロケーターは、開発ビルドとリリースビルドで異なる使用状況レポートを生成します。これは、開発ビルドでは、各割り当てに追加の 40B のヘッダーが配置されているためです。以下の図は、16B 割り当てと 64B 割り当ての開発ビルドとリリースビルドの違いを示しています。
アロケーターが 4MB のうち 2MB だけを割り当てた後に割り当て可能な容量がなくなったと報告するのは、このヘッダーが原因です。
[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
バケットアロケーターに割り当て可能な空き容量がなくなった場合、割り当ては別のアロケーターにフォールバックします。使用状況レポートには、失敗した割り当ての数など、使用状況の統計が表示されます。レポートに失敗回数が直線的に増加していることが表示されている場合は、ロードではなくフレームの計算時に割り当てが失敗した可能性があります。フォールバック割り当てはシーンのロードには問題ありませんが、フレームの計算時に発生するとパフォーマンスに影響する可能性があります。
これらのフォールバック割り当てを回避するには、ブロックサイズを引き上げ、シーンのロード時のピーク使用量ではなく、フレームのピーク使用量に一致するように新しいブロックサイズを制限します。これにより、ブロックが過剰に大規模になり、大量のメモリが予約されてランタイムにメモリが使用できなくなるのを防止できます。
ヒント: プロファイラーアロケーターは、バケットアロケーターのインスタンスを共有します。この共有インスタンスは、プロファイラーの共有バケットアロケーターでカスタマイズできます。