Skip to content

Reduce static memory retention of decoded OpenAPI specs during test runs #38

@wadakatu

Description

@wadakatu

Problem

大規模テストスイート(2,700+ tests)でこのパッケージを使用すると、OpenApiSpecLoader::$cache にデコードされたJSON specが静的に保持され、テスト全体を通じてメモリから解放されません。

当プロジェクトでは front.json(5.5MB)をデコードした PHP 配列だけで 約16MB を消費しており、extension全体で 約20MB のメモリオーバーヘッドが発生しています。

通常実行:          515.50 MB
--no-extensions:   495.50 MB
差分:              ~20 MB

Root Cause

OpenApiSpecLoader$cachestatic array で保持されており、一度ロードされたspecはプロセス終了まで解放されません。

// OpenApiSpecLoader.php
private static array $cache = [];

public static function load(string $specName): array
{
    if (isset(self::$cache[$specName])) {
        return self::$cache[$specName];
    }
    // ... file_get_contents + json_decode ...
    self::$cache[$specName] = $decoded;
    return $decoded;
}

加えて、OpenApiResponseValidator がアサーションごとに新規インスタンスを生成し、OpenApiPathMatcher がその都度正規表現をコンパイルしています。

Suggestions

  1. WeakReference / オンデマンドロード: specを WeakReference で保持するか、バリデーション完了後にキャッシュをクリアするオプションを提供する

  2. PathMatcher の再利用: OpenApiPathMatcher をspec単位でキャッシュし、毎回の正規表現コンパイルを避ける

  3. 必要な部分だけロード: バリデーション対象のエンドポイントに必要なスキーマだけを抽出し、spec全体をメモリに保持しない(lazy loading)

  4. spec キャッシュの手動クリアAPI: OpenApiSpecLoader::reset() は存在するが自動的に呼ばれない。テストクラス間でリセットするオプションを提供する

Environment

  • PHP 8.4
  • PHPUnit 13.0.5
  • openapi-contract-testing v0.10.0
  • front.json: 5.5MB (144,497 lines)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions