Instruments — は、iOS、macOS、tvOS、watchOSアプリケーションのパフォーマンス解析のためにXcodeに組み込まれたプロファイラです。このツールは、CPU、メモリ、ネットワーク、グラフィックス、エネルギー消費をリアルタイムで測定するためのテンプレートセットを提供します。Apple Developer Documentationによると、Instrumentsは開発の全段階(リークの発見からアプリケーション起動時間の最適化まで)で使用されています。
重要なポイント
Instruments — は、Xcodeの一部であり、Sun Microsystemsが開発したDTraceテクノロジーに基づくプロファイリングおよびトレーシングシステムです。Instrumentsは数十のプロファイリングツール(テンプレート)を単一のインターフェースに統合します:テンプレートを選択し、Xcodeからアプリケーションを起動してデータ収集を開始するだけです。
Instrumentsのアーキテクチャはクライアント-サーバーモデルに基づいています:デバイス上のエージェントがデータを収集し、USB接続を介してMacに送信します。これにより、プロファイラがアプリケーションのパフォーマンスに与える影響を最小限に抑えます — Instrumentsは主にホスト側で動作します。WWDC 2022によると、1msサンプリングレートでのTime Profilerのオーバーヘッドは3%未満です。
Instrumentsはカスタムテンプレートをサポートしています — 開発者は1回のプロファイリングセッションで複数のツールを組み合わせることができます。例えば、Time Profiler + Allocations + Leaksを同時に起動し、CPUピークとメモリアロケーションの相関関係を確認できます。これにより、各コンポーネントを個別に分析するだけでは得られない、パフォーマンスの全体像が得られます。
Xcodeには16のプリインストールされたInstrumentsテンプレートが付属しています:Time Profiler、Allocations、Leaks、Energy Log、Network、Core Animation、Metal System Trace、File Activity、System Traceなど。各テンプレートは特定のタスクに最適化され、適切なトリガーとフィルター設定で事前構成されています。
Time Profiler — は最も使用されるInstrumentsテンプレートです。コールスタックサンプリングに基づいて動作します:1〜10ミリ秒ごとに、システムがアプリケーションの全スレッドのコールスタックを記録します。セッション停止後、Instrumentsはサンプルを集計し、どのメソッドと関数が最も時間を消費したかを表示します。結果はCall Tree(自己重み順にソートされたコールツリー)として表示されます。
Time Profilerの主要メトリックはSelf Weight(子メソッドの呼び出しを除いた、メソッド内で直接費やされた時間)です。実際にプロセッサに負荷をかけている関数を示すのはSelf Weightです。Weight(子メソッドを含む総時間)は誤解を招く可能性があります:Weightが高いメソッドは単に別の低速メソッドを呼び出しているだけで、自身は高速かもしれません。
import UIKit
class ImageGalleryViewController: UIViewController {
// Time ProfilerはcellForItemAtのSelf Weight = 40%を示します
// その内部でdecodeImageが35%を占める — これがボトルネックです
func collectionView(
_ collectionView: UICollectionView,
cellForItemAt indexPath: IndexPath
) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(
withReuseIdentifier: "ImageCell",
for: indexPath
) as! ImageCell
// ❌ decodeImage — ボトルネック(Self Weight = 35%)
cell.imageView.image = UIImage(contentsOfFile: imagePath)
return cell
}
}
Time Profilerを分析する際は、com.apple.main-threadで実行されているメソッドに注目してください。メインスレッドのSelf Weightがフレームあたり16msのしきい値を超えると、UIが遅くなります。このような問題の解決策は、画像デコード、レイアウト計算、データ処理をGrand Central Dispatch (GCD)を使用してメインスレッドからバックグラウンドスレッドに移動することです。
Call Tree — はSelf Weight順にソートされた全メソッドコールの階層表現です。Call Treeの最も重いメソッドが最初の行です。行を展開すると、そのメソッドがどの子メソッドを呼び出し、それらがどれだけの時間を要したかがわかります。Self Weight(自身の時間)がWeight(総時間)を大幅に超えるメソッドを探してください — これは同期ブロッキングと待機の兆候です。
Allocations — はアプリケーションの全メモリアロケーションを監視するツールです。どのオブジェクトが、どのような数量で、どのような総サイズで各瞬間に作成されているかを示します。Android StudioのMemory Profilerとは異なり、AllocationsはHeapshot(2つのスナップショットを比較できるライブオブジェクトの瞬間スナップショット)をサポートしています。
Allocationsのインターフェースは2つの主要セクションで構成されています:All Allocations(全オブジェクトタイプの総統計)とCall Trees(オブジェクトを作成するメソッド別のコールツリー)。リークを見つけるには、Heapshot Analysisを使用します:シナリオ実行前にスナップショットを取得し、シナリオを実行し、後にスナップショットを取得して、どの新しいオブジェクトがメモリに残っているかを比較します。
Apple Developer Documentationによると、Allocationsで検出される最も一般的なリークパターンは、コレクションスクロール時のUIViewとCALayerの過剰作成です。スクロールのたびにライブUIViewの数が増加するのに、コレクションがセルを再利用している場合 — どこかで追加のビューが古いビューを解放せずに作成されています。Allocationsはこれらのビューが作成されている正確なコールスタックを表示します。
| パラメータ | 説明 | 確認ポイント |
|---|---|---|
| # Living | このタイプの生存オブジェクト数 | シナリオ繰り返し時に安定しているべき |
| # Transient | 期間内に作成・解放されたオブジェクト | 急激なスパイクは過剰アロケーションの兆候 |
| Total Bytes | このタイプの総メモリ量 | デバイスの総利用可能RAMと比較 |
Heapshot — はAllocationsにおける生存オブジェクトの瞬間スナップショットです。シナリオ実行前にHeapshotを取得し、シナリオを実行し、2番目のHeapshotを取得します。スナップショット間の差は、作成され解放されなかったオブジェクトを示します。理想的な結果は一時オブジェクト(Autorelease pool)のみの増加です。正確な分析には、1回のセッションでAllocations + Leaksの組み合わせを使用します。Allocationsはどのオブジェクトが解放されていないかを示し、Leaksはその理由(どの強参照が保持しているか)を示します。リークが疑われるたびにデュアルセッションを実行してください。
Leaks — はiOSおよびmacOSアプリケーションのメモリリーク検出に特化したツールです。単にアロケーションを表示するAllocationsとは異なり、Leaksはretain cycles(2つ以上のオブジェクトが互いに強参照で保持し合う状況)を探してヒープを積極的にスキャンします。
LeaksはCycles & Roots(オブジェクト保持グラフのビジュアライザ)と連携して動作します。リークが検出されると、Leaksはサイクル内の全オブジェクト、それらのretain count、参照が渡される正確なフィールドを表示します。開発者はグラフを見て、どの参照をweakに置き換える必要があるかを理解するだけです。
このツールはタイムライン上でリークを赤いマーカーで自動的にハイライトします。Leaksはリアルタイムで動作します:システムがリークを検出するとすぐに開発者に通知します。これにより、ダンプやポスト分析を待たずにその場で問題を修正できます。
WWDC 2022によると、Leaksは複雑なマルチレベルretain cycles(例えば、3つ以上のオブジェクトが強参照の閉じたチェーンを形成する場合)も検出できます。このようなサイクルの診断にはCycles & Rootsグラフが不可欠です:オブジェクトが互いにどのように閉じているかを視覚的に示します。
グラフの各ノードはオブジェクト、各矢印は強参照です。サイクルは矢印の閉じたループです。ノードの色はステータスを示します:赤 — リークしたオブジェクト、緑 — ルート(GC Root)、灰 — 中間オブジェクト。リークを修正するには、ロジックを壊さずにweakにできる矢印を見つけ、コード内の参照タイプを変更します。
Energy Log — はアプリケーションのエネルギー消費を測定するInstrumentsテンプレートです。デバイスのハードウェアセンサー(CPU負荷、Wi-Fiおよびセルラー無線の状態、GPS使用、ディスプレイ、Bluetooth)からデータを収集します。Energy Logはアプリケーション内のどの操作が最もバッテリーを消費するかを示し、それらを時間軸上のエネルギー消費グラフに重ね合わせます。
このツールは操作をエネルギー消費レベルで分類します:低(通常のプロセッサ動作)、中(Wi-Fi送信)、高(GPS、モバイルネットワーク、GPU)。Energy Logが長期間にわたって高レベルの赤いインジケータを表示する場合 — アプリケーションがバックグラウンドでバッテリーを消耗しており、ユーザーに削除されます。
Energy Logで特定される典型的な問題:時間制限なしのWakeLock(タスク完了後にプロセッサをアクティブに保つ)、バックグラウンドでの高精度Location Updates(数秒ごとの座標要求)、ネットワークセッションの異常(サーバーへの頻繁な再接続)。Energy Logはそのようなインシデントを記録し、エネルギー消費の多い操作を停止する条件を追加することを推奨します。
エネルギー消費のテストには、バッテリー駆動の実機を使用してください — エミュレータではエネルギー消費の指標は不正確です。CIでのバッテリー消費チェックを自動化するために、Energy LogをUIテストと一緒に実行してください。
Instrumentsの起動はXcodeから2つの方法で行えます:Product → Profile(⌘I)メニューから、またはLaunchpadから個別のアプリケーションとしてInstrumentsを開く。最初の方法が便利です:Xcodeが自動的にアプリケーションをプロファイリングモードでビルドし、選択したテンプレートで接続されたデバイス上で実行します。セッション停止後、Instrumentsはトレースを.trace拡張子のファイルに保存します。
結果の解釈はテンプレートによって異なります。Time Profilerの場合はSelf Weight順にソートされたCall Treeを見てください — 上部のメソッドが主要なボトルネックです。Allocationsの場合は — 循環シナリオ後の# Livingを確認:オブジェクト数が増加したらリークを探します。Leaksの場合は — 赤いマーカーとCycles & Rootsグラフを確認します。最適化の前後で結果を比較してください — これが変更の有効性を確認する唯一の方法です。
// CIのためのInstrumentsコマンドライン
// CI/CDパイプラインへのInstruments統合
import XCTest
class PerformanceTests: XCTestCase {
func testScrollPerformance() {
// コレクションスクロール時間の測定
measure(metrics: [XCTCPUMetric(), XCTMemoryMetric()]) {
app.scrollToBottom()
}
}
}
CIでは、xcodebuild -showBuildSettingsおよびxcrun xctraceを使用してコマンドラインからInstrumentsを実行できます。これにより、コミットごとにプロファイリングを自動化し、リグレッションを見逃しません。分析にはベースライン比較を使用します:メトリックが前のコミットより5%悪化した場合、パイプラインを停止する必要があります。
Instruments使用時の主なエラー:デバイスではなくシミュレータでのプロファイリング(CPUおよびGPUデータが不正確)、シナリオなしでのデータ収集(結果がランダム)、Call Treeの無視(グラフのみを見て、具体的なメソッドを見ない)。これらのエラーを修正することで、プロファイリングの品質が80%向上します。
よくある質問
はい、InstrumentsはSwiftUIを完全にサポートしています。UIパフォーマンス分析にはCore Animationテンプレートを使用してください — フレームレンダリング速度を表示し、不要なViewの再レンダリングを特定します。Time ProfilerとAllocationsも制限なくSwiftUIで動作します。
Instruments — はAppleエコシステム全体のための汎用プロファイラであり、CPU、メモリ、ネットワーク、グラフィックス、エネルギー消費をカバーします。Shark — はLeakCanaryの内部ヒープダンプアナライザであり、Androidでのメモリリーク検出に特化しています。
Instrumentsはアプリケーションコードに埋め込まれません — Xcodeを介して実行中のプロセスに接続する外部ツールです。コードの変更は一切不要です。.traceファイルはバイナリに含まれない単なるログです。
標準の1msサンプリングレートでは、Time Profilerのオーバーヘッドは3%未満です。正確なトレースモード(関数呼び出しごと)では、オーバーヘッドが20〜30%に達する可能性があるため、日常的なプロファイリングにはサンプリングが使用されます。正確なトレースはクリティカルな部分にのみ必要です。
結果は自動的にプロジェクトフォルダの.traceファイルに保存されます。このファイルは別のMacでXcodeを使って開き、共同分析が可能です。テキスト形式でエクスポートするには、xcrun xctrace export --input file.trace --output result.xmlを使用します。
まとめ
ターンキー方式のモバイルアプリケーションを開発します
IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。