

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

# のメモリ管理 AWS SDK for C\$1\$1
<a name="memory-management"></a>

 AWS SDK for C\$1\$1 は、ライブラリ内のメモリの割り当てと割り当て解除を制御する方法を提供します。

**注記**  
カスタムメモリ管理を利用できるのは、コンパイル時定数 `USE_AWS_MEMORY_MANAGEMENT` を定義してビルドされたライブラリを使用する場合のみです。  
コンパイル時定数なしでビルドされたバージョンのライブラリを使用した場合、`InitializeAWSMemorySystem` などのグローバルなメモリシステム関数は機能せず、代わりにグローバルな `new` および `delete` 関数が使用されます。

コンパイル時定数の詳細については、[「STL and AWS Strings and Vectors](#stl-and-aws-strings-and-vectors)」を参照してください。

## メモリの割り当てと解放
<a name="allocating-and-deallocating-memory"></a>

 **メモリを割り当てまたは解放するには** 

1. サブクラス `MemorySystemInterface`: `aws/core/utils/memory/MemorySystemInterface.h`。

   ```
   class MyMemoryManager : public Aws::Utils::Memory::MemorySystemInterface
   {
   public:
       // ...
       virtual void* AllocateMemory(
           std::size_t blockSize, std::size_t alignment,
           const char *allocationTag = nullptr) override;
       virtual void FreeMemory(void* memoryPtr) override;
   };
   ```
**注記**  
必要に応じて `AllocateMemory` の型シグネチャを変更できます。

1. `Aws::SDKOptions` 構造体を使用して、カスタムメモリマネージャーの使用を設定します。構造体のインスタンスを `Aws::InitAPI` に渡します。アプリケーションの終了前に、同じインスタンスで `Aws::ShutdownAPI` を呼び出し、SDK をシャットダウンする必要があります。

   ```
   int main(void)
   {
     MyMemoryManager sdkMemoryManager;
     SDKOptions options;
     options.memoryManagementOptions.memoryManager = &sdkMemoryManager;
     Aws::InitAPI(options);
   
     // ... do stuff
   
     Aws::ShutdownAPI(options);
   
     return 0;
   }
   ```

## STL AWS 、文字列、ベクトル
<a name="stl-and-aws-strings-and-vectors"></a>

メモリマネージャーで初期化すると、 AWS SDK for C\$1\$1 はすべての割り当てと割り当て解除をメモリマネージャーに延期します。メモリマネージャーが存在しない場合、SDK はグローバルな new と delete を使用します。

カスタム STL アロケーターを使用する場合は、すべての STL オブジェクトの型シグネチャをアロケーションポリシーに合わせて変更する必要があります。SDK の実装とインターフェイスで STL が広く使用されているため、SDK で 1 つの方式を採用すると、デフォルトの STL オブジェクトの直接的な受け渡しや割り当て制御が難しくなります。あるいは、内部ではカスタムアロケーターを使用しつつ、インターフェイスでは標準およびカスタム STL オブジェクトの両方を許容するハイブリッド方式も考えられますが、この方式ではメモリ問題の調査が難しくなる可能性があります。

この問題への解決策は、メモリシステムのコンパイル時定数 `USE_AWS_MEMORY_MANAGEMENT` を用いて、SDK が使用する STL 型を制御することです。

コンパイル時定数が有効になっている場合 (オン）、タイプは AWS メモリシステムに接続されたカスタムアロケーターを使用して STL タイプに解決されます。

コンパイル時定数が無効 (off) の場合、すべての `Aws::*` 型は対応するデフォルトの `std::*` 型に解決されます。

 **SDK の `AWSAllocator.h` ファイルからのコード例** 

```
#ifdef USE_AWS_MEMORY_MANAGEMENT

template< typename T >
class AwsAllocator : public std::allocator< T >
{
   ... definition of allocator that uses AWS memory system
};

#else

template< typename T > using Allocator = std::allocator<T>;

#endif
```

コード例では、`AwsAllocator` はコンパイル時定数に応じてカスタムアロケーターまたはデフォルトアロケーターになります。

 **SDK の `AWSVector.h` ファイルからのコード例** 

```
template<typename T> using Vector = std::vector<T, Aws::Allocator<T>>;
```

このコード例では、`Aws::*` 型を定義しています。

コンパイル時定数が有効になっている場合 (オン）、タイプはカスタムメモリ割り当てと AWS メモリシステムを使用してベクトルにマッピングされます。

コンパイル時定数が無効 (off) の場合、この型はデフォルトの型パラメータを持つ通常の `std::vector` に解決されます。

型エイリアスは、コンテナ、文字列ストリーム、文字列バッファなど、SDK 内でメモリ割り当てを行うすべての `std::` 型に使用されます。はこれらのタイプ AWS SDK for C\$1\$1 を使用します。

## 残された課題
<a name="remaining-issues"></a>

SDK 内のメモリ割り当ては制御できますが、STL 型は依然としてモデルオブジェクトの `initialize` および `set` メソッドの文字列パラメータを通じて、パブリックインターフェイスに多く使用されています。STL を使用せずに、代わりに文字列やコンテナを使用している場合、サービス呼び出しのたびに多くの一時オブジェクトを作成する必要があります。

STL を使用せずにサービス呼び出しを行う際の一時オブジェクトやメモリ割り当てを削減するために、次の対策を実装しています。
+ 文字列を受け取るすべての Init/Set 関数には、`const char*` を受け取るオーバーロードがあります。
+ コンテナ (マップ/ベクター) を受け取る Init/Set 関数には、1 つのエントリを受け取る add バリアントがあります。
+ バイナリデータを受け取る Init/Set 関数には、データへのポインタと `length` 値を受け取るオーバーロードがあります。
+ (オプション) 文字列を受け取るすべての Init/Set 関数には、ゼロ終端されていない `const char*` と `length` 値を受け取るオーバーロードもあります。

## ネイティブ SDK デベロッパー向けメモリ制御
<a name="native-sdk-developers-and-memory-controls"></a>

SDK コード内では次のルールに従います。
+ `new` と `delete` は使用せず、代わりに `Aws::New<>` と `Aws::Delete<>` を使用します。
+ `new[]` と `delete[]` は使用せず、`Aws::NewArray<>` と `Aws::DeleteArray<>` を使用します。
+ `std::make_shared` を使用せず、`Aws::MakeShared` を使用します。
+ 1 つのオブジェクトへの一意のポインタには `Aws::UniquePtr` を使用します。一意のポインタを生成するには、`Aws::MakeUnique` 関数を使用します。
+ オブジェクトの配列への一意のポインタには、`Aws::UniqueArray` を使用します。一意のポインタを生成するには、`Aws::MakeUniqueArray` 関数を使用します。
+ STL コンテナを直接使用しないでください。`Aws::` typedef のいずれかを利用するか、必要なコンテナに typedef を追加してください。例えば、次のようになります。

  ```
  Aws::Map<Aws::String, Aws::String> m_kvPairs;
  ```
+ SDK に渡して管理される外部ポインタには `shared_ptr` を使用します。共有ポインタは、オブジェクトの生成方法に合った破棄ポリシーで初期化する必要があります。SDK がポインタのクリーンアップを行わない場合は、生ポインタを使用できます。