Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

内存管理

VSAG 在关键路径上大量使用自定义 AllocatorResource,允许用户:

  • 接入业务侧已有的内存池;
  • 对索引内存占用进行度量与上限控制;
  • 在多进程 / NUMA 环境下精细分配内存来源。

自定义 Allocator

class MyAllocator : public vsag::Allocator {
public:
    std::string Name() override { return "my_allocator"; }
    void* Allocate(size_t size) override;
    void Deallocate(void* p) override;
    void* Reallocate(void* p, size_t size) override;
    // ...
};

auto allocator = std::make_shared<MyAllocator>();
auto resource = std::make_shared<vsag::Resource>(allocator, /*thread_pool=*/nullptr);
auto engine = vsag::Engine(resource);

auto index = engine.CreateIndex("hgraph", build_params).value();

完整示例参见 examples/cpp/201_custom_allocator.cpp

搜索路径上的临时 Allocator

KnnSearch / RangeSearch 支持为单次搜索注入临时 Allocator,用于在线程局部的 arena 中分配工作区, 避免与全局堆竞争:

vsag::SearchParam search_param;
search_param.allocator = thread_local_allocator.get();
auto result = index->KnnSearch(query, k, search_param);

示例:examples/cpp/313_feature_search_allocator.cppexamples/cpp/314_feature_hgraph_search_allocator.cpp

估算与查询内存占用

EstimateMemory(data_num)

Index::EstimateMemory(data_num) 返回索引在插入 data_num 条向量后预期占用的字节数。它仅基于 构建参数(dim、量化方式、max_degree 等)推算,不会分配任何向量存储,因此可以在空索引上安全 调用,是入库前评估节点规格的推荐方式:

if (index->CheckFeature(vsag::SUPPORT_ESTIMATE_MEMORY)) {
    uint64_t estimated = index->EstimateMemory(1'000'000);  // 字节
}

完整示例:examples/cpp/308_feature_estimate_memory.cpp

GetMemoryUsage()

Index::GetMemoryUsage() 返回索引当前占用的字节数:

int64_t bytes = index->GetMemoryUsage();

特性:

  • 所有索引类型均实现了该方法,但只有通过 CheckFeature 公布 vsag::SUPPORT_GET_MEMORY_USAGE 的索引才保证返回有意义的数值。HGraph、IVF、BruteForce、Pyramid、WARP 均声明了该能力 (见 src/algorithm/{hgraph,ivf,brute_force,pyramid,warp}.cpp);SINDI 出于 接口纯虚函数的要求实现了该方法,但当前未设置该 feature flag,请仅把返回值视为参考信息。
  • 线程安全;可与搜索并发轮询。
  • 延迟在微秒量级 —— 适合生产环境的实时内存监控。
  • 统计的是索引自身占用的内存(向量、图、量化器状态)。该值通常小于操作系统层面观察到的 RSS: RSS 还包含 allocator 的开销、临时 scratch buffer、以及索引外部持有的数据(例如用户自有的输入 向量缓冲)。SINDI 索引尤其建议在构建完成之后调用 GetMemoryUsage() 才能拿到具有代表性的 数值。

可运行示例:examples/cpp/319_feature_get_memory_usage.cpp,其中包含一个辅助函数将接口值与进程 驻留内存进行对照。

能力标志

标志含义
vsag::SUPPORT_ESTIMATE_MEMORY支持 EstimateMemory(data_num)
vsag::SUPPORT_GET_MEMORY_USAGE支持 GetMemoryUsage()

两个标志均可通过 index->CheckFeature(...) 查询 —— 参见 索引自省

线程池

Resource 也接受用户提供的 ThreadPool,与 Allocator 配合可完全托管并行度与资源归属。见 examples/cpp/203_custom_thread_pool.cpp

注意事项

  • 自定义 Allocator 必须是线程安全的。
  • Allocator 生命周期必须覆盖所有引用它的索引与结果对象。
  • 若未显式指定,VSAG 会创建一个默认的基于 malloc 的 allocator。