3 バージョン(v1.6 / v1.7 / 現行)の実機 MEMMONITOR 計測結果をまとめる.計測の目的・手段・移植方針・指標定義は PLAN_04_性能評価計測計画 を参照する.
Debug|x64,MEMMONITOR 有効・WHITEBOARD 無効.private_MB(Process.PrivateMemorySize64).bench/*)はプレビューが毎フレーム Invalidate() で本体 UI スレッドを埋めるため,観測窓を専用 UI スレッドで開く(本体・プレビューの挙動は不変の観測側の措置.同一スレッドだとグラフ描画とサンプリングが WM_PAINT 洪水に飢餓し,サンプル間隔が乱れるため).現行はタイマー駆動で飢餓しないため同一スレッドのまま計測した.現行で実測した 1 本の記録を基準とし,撮影・校正の秒数を全版で揃える.撮影は単発撮影(1 枚撮影)の繰り返し.
| 時刻 | 動作 |
|---|---|
| 0〜32 秒 | プレビュー放置(副モニタ ON) |
| 32.5〜36.1 秒 | 校正 1 回(処理時間 約 3.5 秒.アプリ側処理で固定) |
| 62 / 92 / 123 秒 | 単発撮影(約 30 秒間隔で 3 回) |
| 123〜303 秒 | プレビュー放置(約 180 秒.プレビュー経路リークの観測区間) |
| 303 秒 | 単発撮影 1 回 |
| 約 348 秒 | 停止・CSV 保存 |
旧版(v1.6 / v1.7)もこの秒数・順序・撮影間隔に合わせて再現し,同じ時間軸で 3 版を重ねて比較する.
データ: data/perf_current.csv(689 サンプル・約 348 秒).
| 指標 | 値 |
|---|---|
private_MB アイドル時ベースライン | 約 150 MB |
private_MB 校正後の定常包絡線 | 約 180〜200 MB(約 348 秒を通じて水平) |
| 撮影時の一時ピーク | 452〜509 MB(1〜2 秒で ~180 MB に完全復帰) |
終端(348 秒)の private_MB | 約 182 MB(校正後ベースラインと同一) |
gdi_objects / handle_count | 68〜95 / 780〜855(単調増加なし) |
| 指標 | 値 |
|---|---|
main_copy_ms(FastClone コピー時間) | 大半 2.3〜2.8 ms(平均 約 2.6 ms.周期的に 5〜6 ms のスパイク) |
callback_fps(ShowImage 実効レート) | 約 30(カメラレート律速) |
| 本モニタ実描画 FPS | 約 19 で一定 |
| 副モニタ実描画 FPS | 約 19 で一定(飢餓なし) |
callback_fps ≈2.5・FPS ≈1 に落ちるのは,撮影が UI を約 1.5 秒同期ブロックし 500ms サンプラが 1 コマ捉えたもの.1 サンプルだけの谷で即回復=正常挙動.データ: data/perf_v1.7.csv(436 サンプル・約 315 秒).bench/v1.7(v1.7 に bench/v1.6 の移植を cherry-pick.v1.7 の保存経路メモリ効率化と観測フックが両立)で基準プロトコルを再現.計測マッピングは v1.6 と同じ(main_copy_ms ≈ 0,全画面コピーは sub_copy_ms).
v1.7 は v1.6 + 保存経路のメモリ効率化のみでプレビュー経路は v1.6 と同一構造.結果もそれを裏付ける.
| 指標 | v1.7 | (参考)v1.6 |
|---|---|---|
private_MB ピーク包絡線 | 30s:302 → 90s:597 →(以降)~600〜705 MB で高止まり | ~834→660〜893 MB |
private_MB トラフ | 約 150〜296 MB | 約 140〜200 MB |
sub_copy_ms | 44.9 ms | 45.7 ms |
callback_fps | 17.2 | 17.0 |
副モニタ FPS sub_paint_fps | 2.94(436 中 76 行が 0) | 2.93(75 行が 0) |
gdi_objects / handle_count 最大 | 136 / 889 | 122 / 889 |
callback_fps ~17・副モニタ飢餓 ~3fps).v1.7 がプレビュー経路に手を付けていないことをデータが裏付ける.SaveThread の Mat 都度 Dispose+校正時の中間 Mat 解放).ただしプレビュー経路のリークは残るため,放置区間でも上昇は続き,現行のような平坦な天井にはならない.データ: data/perf_v1.6.csv(436 サンプル・約 338 秒).bench/v1.6(v1.6 タグに MEMMONITOR 計測スカフォールドを観測フックのみ移植・プレビューのロジックは不変)で基準プロトコルを再現.
v1.6 は本モニタが生フレームを直接使いコピーを持たないため main_copy_ms ≈ 0.毎フレームの全画面 Bitmap コピー(new Bitmap(bmp)=FastClone 前の実装)は副モニタ用の sub_copy_ms に現れる.FastClone 比較はこの sub_copy_ms で読む.
| 指標 | 値 |
|---|---|
private_MB 開始ベースライン | 約 200 MB |
private_MB ピーク包絡線(30 秒バケットの最大) | 30s:276 → 60s:539 → 90s:834 MB と上昇し,以降 660〜893 MB で高止まり・大振動 |
private_MB トラフ(谷) | 約 140〜200 MB(GC+ファイナライザによる周期的一掃) |
gdi_objects / handle_count 最大 | 122 / 889(暴走なし) |
new Bitmap=原因1,副モニタ取りこぼしフレームの未 Dispose=原因2/3 が積み上がり,GC+ファイナライザが周期的にネイティブメモリを一掃するのこぎり波).現行の平坦な ~200 MB 天井と対照的.| 指標 | 値 |
|---|---|
sub_copy_ms(new Bitmap 全画面コピー) | 平均 45.7 ms(425 フレーム平均) |
main_copy_ms | 0(v1.6 本モニタはコピーなし) |
callback_fps(ShowImage 実効レート) | 平均 17(最小 ~2) |
副モニタ実描画 FPS sub_paint_fps | 平均 2.9(436 中 75 行が 0)=描画飢餓 |
callback_fps を ~17 に抑える.sub_paint_fps ≈3(しばしば 0)でほとんど描画されない=PLAN_03 の副モニタ描画飢餓が旧版で実証された.3 版すべてを同一基準プロトコル(副モニタ ON)で計測した結果.
| 指標 | v1.6 | v1.7 | 現行 |
|---|---|---|---|
メモリ private_MB 包絡線 | ~200→834 MB,140〜890 MB で振動 | ~200→**~700** MB,150〜705 MB で振動 | ~180〜200 MB で水平(撮影時のみ一時 ~450→即復帰) |
| 毎フレーム全画面コピー | sub_copy_ms ~46 ms(new Bitmap) | ~45 ms(同上) | ~2.6 ms(FastClone) |
callback_fps | ~17(コピー律速) | ~17(同上) | ~30 |
副モニタ FPS sub_paint_fps | ~3(しばしば 0)=飢餓 | ~3(同上) | ~19 で一定 |
| GDI / handle 最大 | 122 / 889 | 136 / 889 | 同程度(枯渇なし) |
改善は 2 経路・2 段階で起きたことが定量的に確認できた.
SaveThread/校正の Mat 解放).単発撮影プロトコルのため差は控えめだが方向は明確(連続撮影での隔離値は TEST_03).callback_fps ~17 → ~30,副モニタ ~3fps(飢餓)→ ~19fps,メモリ包絡線 ~700 MB(上昇)→ ~200 MB(平坦・リーク解消).v1.6/v1.7 のプレビュー指標が数値まで一致することが,この経路が v1.7 まで未修正だった裏付けになる.