> ## Documentation Index
> Fetch the complete documentation index at: https://devdocs.xbox.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Memory management in the PlayFab Unified SDK

> Manage memory in the PlayFab Unified SDK with PFMemoryHooks custom allocators, safe XAsyncBlock lifetime patterns, and explicit handle cleanup.

This guide explains how memory is managed in the PlayFab Unified SDK, including customization options and best practices to avoid memory leaks and ensure safe handling of asynchronous operations.

## Overview

The PlayFab Unified SDK gives developers precise control over memory usage by supporting **custom allocation hooks**, **explicit resource cleanup**, and **safe async operations handling**. This makes it suitable for high-performance or resource-constrained environments such as games and embedded platforms.

## Custom Memory Allocation

The SDK allows you to define custom memory allocation and deallocation functions using `PFMemoryHooks`. This lets you integrate the SDK into your existing memory management systems, such as arenas, pools, or platform-specific allocators.

### Setting Custom Memory Hooks

```cpp theme={null}
void* MyCustomAlloc(size_t size, uint32_t memoryTypeId);
void MyCustomFree(void* ptr, uint32_t memoryTypeId);

PFMemoryHooks memoryHooks = { MyCustomAlloc, MyCustomFree };
PFMemSetFunctions(&memoryHooks);
PFServicesInitialize(nullptr); // Must be called after setting memory hooks
```

**Notes:**

* Hooks must be set **before** calling `PFServicesInitialize`.
* They **cannot** be changed once the SDK is initialized.
* If not set, the SDK defaults to standard allocation (`malloc`/`free`).

## Asynchronous Operations

Most API calls in the SDK are asynchronous. Each async call requires a valid `XAsyncBlock` which must remain alive for the duration of the request.

### Using `XAsyncBlock` Safely

```cpp theme={null}
auto asyncBlock = std::make_unique<XAsyncBlock>();
asyncBlock->callback = [](XAsyncBlock* block)
{
    // Retrieve result, then delete asyncBlock if needed
};
StartAsyncPlayFabCall(asyncBlock.get());
asyncBlock.release(); // Ownership passed; handle lifetime carefully
```

**Best Practices:**

* Don't stack-allocate `XAsyncBlock` unless you can guarantee its lifetime.
* Release ownership if dynamically allocated, and clean up in the callback.
* Avoid capturing invalidated references or pointers in the lambda.

## Resource Cleanup

The SDK uses handles (e.g., `PFEntityHandle`, `PFServiceConfigHandle`) that **must** be explicitly closed when no longer needed.

### Closing Handles and Uninitializing

```cpp theme={null}
PFEntityCloseHandle(entityHandle);
PFServiceConfigCloseHandle(serviceConfigHandle);

// Gracefully uninitialize the SDK
XAsyncBlock async{};
PFServicesUninitializeAsync(&async);
XAsyncGetStatus(&async, true); // Blocks until cleanup completes
```

**Important:**

* Always close PlayFab handles to prevent leaks.
* Wait for `PFServicesUninitializeAsync` to complete before shutting down.

## Best Practices

* **Set memory hooks early**: Before any other PlayFab API calls.
* **Avoid memory leaks**: Close handles and manage async resources carefully.
* **Use memory profilers**: Especially on platforms with tight memory budgets.
* **Use pooled allocators**: For performance-critical or frequent allocations.

## See also

* [Asynchronous operations](/services/playfab/sdks/unified-sdk/async-model)
* [Memory management](/services/playfab/sdks/unified-sdk/memory-management)
* [Tracing and diagnostics](/services/playfab/sdks/unified-sdk/debug-trace)
