ストリーミングはほとんどのブラウザと
Developerアプリで視聴できます。
-
メモリ問題の検出と診断
Xcodeでメモリパフォーマンスの問題を理解し診断する方法を確認します。Xcodeのツールの最新アップデート、Metricsの詳細、XCTestのmemgraphコレクション機能のチェック、Performance XCTestを使って不具合を見つける方法を確認します。
リソース
関連ビデオ
WWDC23
WWDC22
WWDC21
WWDC19
WWDC18
-
ダウンロード
初めまして OS Performanceチーム所属の エンジニア Tanujaです 今日 同僚のStefanと アプリケーションの メモリの問題の診断について 説明します 始めに メモリの使用状況が どうアプリケーション実行に 影響するか 見ていきましょう
次に メモリ使用状況を 確認することで 発生可能な システム障害を いくつか説明 したいと思います
早速 本題に入ります
冒頭に なぜメモリの 容量管理が必要か 明確に述べる べきだと思います メモリの容量を管理すると ユーザー体験の劇的な 向上が実感できるからです 限られたメモリの 容量を管理する事で メモリ再利用の際の システムの一時的な停止を 防ぎ Appの起動時間を 早くします
メモリのロードに 費やす長い時間と 同時に バックグラウンドで Appの 起動も可能であり これはかなり有利で システム使用中に メモリの容量を 圧縮することで Appの立ち上げ時間が 短縮されます
メモリ使用率を 減らすことで ユーザーは Appの新機能から ダイナミックで レスポンシブな応答性を 確保できます
Appからのメモリへのロードを 戦略的に行う事で メモリ再利用クレーム時の Appの対応時間の 遅れを抑制できます
更に 戦略的な メモリの使用により アニメーションを含む 動画のローディングや その他のAppの新機能が 追加でき ユーザーへの 利便性が高まります
最新の機種は デバイスの進化により メモリ容量が 大きいです メモリの容量を 減らすことで 古い機種でも 最新デバイス同様の 性能をユーザーに 提供できます
メモリの容量の 管理を充実すれば Appの起動時間を短縮し レスポンシブな応答性や 複雑な機能が実現し 多様なデバイスで 使用できるでしょう 今度は メモリの容量と 構成について説明します
Appのメモリ プロファイルは下記の 三つに割り当てられます: ダーティメモリ、 圧縮メモリと クリーンメモリです 今の三つのメモリの種類 詳しく見ていきましょう
ダーティメモリは書き込みを 含むバッファ済みデータで mallocを使用する際の 全てのヒープ領域の メモリ割り当て バッファ された復号化画像や フレームワークも含まれます
圧縮メモリとは 圧縮済みの ダーティ・ページで 最近 アクセスされていない データメモリです これらのページは アクセスすると展開します
尚 iOSは macOSと違い スワップ機能はありません
最後は クリーンメモリです クリーンメモリでは 不要なデータを 仮想メモリ等へ移動できます 例えば 画像等で ディスク上と メモリ上でアクセス可能な メモリにマップされたファイルです 又 そのフレームワークです
Appの メモリの容量と言えば 今回は 主にダーティメモリと 圧縮メモリを指します クリーンメモリは 今回の内容から除外です
これら メモリの容量に 関しての説明は ハイレベルな理解です より詳細な 情報は WWDC 2018の "iOSメモリについて理解を深める"を ご参照ください メモリの容量を 確認する際の 管理ツールを 紹介していきます
Xcodeは メモリ効率の 改善のため Appの開発から 作成過程まで 使用可能なツールです
XCTestのテスト用 フレームワークでUIテストや メモリの容量管理を ユニットごとに行え 同時に Xcode Organizerや MetricKitを使用し ユーザーの メモリメトリックスを 作成過程で監視できます
以後の説明は XCTestの パフォーマンス計測テストに おいての内容です これらの技術は 一般の作業の 優先順位付けと 調査に使用されます
XCTestの パフォーマンス計測機能で メモリ使用率とCPU使用率 ディスク書き込みや その他をテストできます これから 事例をもとに テスト工程を説明します
事例では 私は ミールプランナーという Appのデベロッパです 一週間分の食事プランの 作成に至って必要な 料理レシピのダウンロードと 保存が可能な 新機能の メモリの使用量を 確認したいのです
パフォーマンス計測では Metrics APIを使用し 料理レシピ保存機能の メモリの使用量を 取得するために 必要なデータを この様に指定します コードブロックで Appの起動開始を指示 APIに計測実行を 手動で定義して 料理レシピの 保存機能を タップし レシピが保存される 機能が起動します
レシピのダウンロードに 30秒割り当てて その後 UIで 更新情報を確認します
XcodeのUIで計測の 実行が可能で テストコードの横にある
灰色のダイヤ印を クリックすると テスト結果が 確認できます UIのドロップダウン式の ポップオーバーで計測した テスト値の 結果表示がされます
個々の イテレーションが 下記の棒グラフで 確認できます
五つ全ての イテレーションの平均が 計算され 表示されます
今回の実行結果を 将来行うテストのための ベースライン計測値に定め 比較値に設定可能です
将来 同じ計測テストを 実行してベースライン以上の 結果値となれば テストは不合格となります このベースライン値からの 差がレグレッションです
レグレッションが表示さた場合 原因を調査してから コード修正をし テストに 合格する様にして下さい
今回のXcode 13では 診断データの収集ができ テストで確認したレグレッションの 改善作業への優先順位付けに 役立つ素晴らしい 新機能が追加されました 診断データのツールで 主なのは"K Trace"と "Memory Graph"です
Ktraceはパワフルかつ 汎用なファイルです Ktraceは 一般のシステム調査や 特殊な問題調査に 便利です 例えば グラフィックス・ パイプラインでの エラーの原因を探ったり メインスレッドの ブロックによって発生した ハングを 修正するのに役立ちます
これら Ktraceの ファイルは通常の 作業工程を変更せずに 同時に使用可能です
もう一つの診断データ機能は "Memory Graph"で メモリ特有の調査には 非常に効果的です "Memory Graph"は Xcodeの ”Visual Debugger"と 使え これから説明する 多数のコマンドラインの ツールとも使用可能です
”Memory Graph”とは ある時点でのアドレス空間の 状態を抜き出した スナップショットです ”Memgraphs”は 個々の仮想メモリ領域と 割り当てられたmalloc ストレージ・ブロックの アドレスと容量を 全て表示し 関連する 領域やブロックを示す ポインタも確保されます ヒープ領域での オブジェクトの配置の 確認やリンクされた フレームワークの データ領域も表示され その他もチェックできます
malloc stack loggingが XCTestでは自動的にONなので 割り当てたオブジェクトの バックトレースが行えます
診断データの 収集を起動するは xcodebuildの コマンドラインツールを パフォーマンステストと 連携機能させ診断データの フラグを表示設定します フラグを表示設定することで Ktraceで空きメモリの データ収集 使用済み メモリを”memgraphs”で 確認できます
テストコードの 指示通りに パフォーマンステスト後は 下記の結果が 画面に表示されます かなりのデータ量ですが 重要な部分を いくつか指摘します
まず 確認してほしいのが テストの合否です テストは 不合格です
結果データの詳細を見ると テストの不合格は レグレッションが 原因と示されています 結果はベースライン値より 平均12%以下という表示です
指定したパスに.xcresultの Result Bundleがあります
xcresultファイルを Xcodeで開くと 上記にあるテスト名の横に メモリの使用量の結果値が 表示されてます
下記にあるテストの ログ記録を拡張し 添付された”memgraphs” 確認して下さい
ダウンロードし解凍後は 2つファイルが表示されます 2つのファイルは malloc stackを確認 するためテストにイテレーションを 余分に追加した結果です イテレーションの 計測を開始する前の memgraphファイルを ”pre"と名付け イテレーションの 計測後の memgraphファイルは ”post"と名付けました この様に区別をすると 個々のイテレーションの メモリの使用増加データの 分析が可能になります
Ktraceと ”memory graph”の使用と malloc stackの 状況ログを取得して イテレーションの調査が 可能になった時点で レグレッション発生の 原因を詮索へ進みましょう 今から 同僚のStefanに 解説のバトンタッチをし memgraphの診断データで 確認できる メモリの使用率の 問題について 説明をします 有難う Tanuja 皆さん 始めまして OS Performanceチームの エンジニアのStefanです これからAppで 発生しうるメモリ 使用率の問題と その診断方法 修正と 解決方法につき説明します
今回は メモリのリークと ヒープ領域を主に ヒープ割り当てと フラグメンテーションの 改善につき説明します 一般的なメモリの 使用率の問題や 修正方法について触れます 後 診断データを 取得するために役立つ コマンドラインも いくつか紹介します コマンドラインツールに 関する詳細は WWDC 2018の"iOSメモリについて 理解を深める" を参考に
まずメモリの リーク検出から始めましょう
リークの発生原因は プログラムがオブジェクトを 参照せずに確保したメモリ 領域が解放できないからです このグラフを参考にすると グレイの矢印線で 参照するオブジェクトを 表示しています 参照するオブジェクトは 必ず一個あります
ここのオブジェクトA そしてBをつなぐ点線を 今回の事例のため 取り除く事にしましょう
参照する オブジェクトが 除去され Bは リークの状態です ダーティな状態だけど 参照がなくプログラムが 確保されたままで 他のプログラムが 使えない状態です この状況を防ぐため リークの修正は必要です
Swiftで一般的なリークの 原因は保持サイクルです 図を見るとオブジェクトAと Bは保持サイクルの現状です 二つのオブジェクトは 相互に参照を保持して 保持されている状態です プログラムが確保したままで 他で使えない状態なので メモリ リークです
Swiftでは参照カウントの 管理を自動的に行う独自の automatic reference countingシステム略称ARCで 大半のリークを防げます UnsafePointerなどARCで 管理されていない オブジェクトを使用する際は 処理が終わる前に 割り当ての解除を 心掛けて下さい
ARCツールの機能だけでは 保持サイクル発生の 完全防止はできません なので コードに強力または 循環参照を使用 しない様にして下さい 循環参照を 使用しないと いけない場合は 弱い参照を使うと 割り当ての 解放になりません
ミールプランナーの Appの事例に戻りましょう Tanujaからの不合格 XCTest ”pre”と”post”の memgraphを確認します まず ”post"memgraph ファイルでメモリ リークを確認します
こうすると Leaksコマンドを memgraphで実行します 結果 これからリークに 関して役立つ情報が 表示されます
結果 合計量240バイトの 4個のリークが確認できます
下記には個々の メモリ リークの詳細が 表示されているので リークの原因が 判明する要素が あるかもしれません
オブジェクトグラフの上記に ”ルート・サイクル”と 表記されているので これは 保持サイクルが確認できる
表示されているコードに エラー判明の要素がいくつかある この保持サイクルには ”MealPlan”と”MenuItem” のオブジェクトが含まれている
XCTestはmalloc stackの ログ状況が起動しているので 個々のメモリ リークの コールスタック割りつけも 表示されます この表示があるので オブジェクトのリーク発生を 検出するのに役立ちます
コールスタックの部分は 自身のコード作成により 確認したいと思います 自らがコード作成したコール スタックの部分があります
populateMealData関数に リーク発生の”MealPlan” オブジェクトが割り当てられています 今からXcodeで 問題の 修正が可能か試します
先程のリークの populateMealData関数です 保持サイクルで確認した ”MealPlan”と”MenuItem” の二つのオブジェクトを ここへ割り当てます addMealToMealPlan関数に 問題がありそうです 詮索します
問題は ”MealPlan”に ”addItemをコールし ”MenuItem”に”addPlan” をコールしたからです 食事プラン全てのアイテムを 表示する機能であり アイテムがどの特定プランの ものかを表示する機能です
ここでは”MealPlan”の ”addItem”で ”MenuItem”を配列に 参照として追加保存してます ここの”MenuItem”の ”addPlan”は参照として 食事プランへ保存してます これで保持サイクルの 状態が明らかになり 強い参照状況が 確認できます
”populateMealData”が ”MealPlan”と ”MenuItem”を 解放すれば 他の参照がないので 孤立してしまいます でも保持し保持されている 状態でリークが発生します
循環参照を使わない 改善策を 探りたいと思います 一時しのぎの修正ですが ”MenuItem”の変更をして 弱参照へ"MealPlan"に 対するオブジェクトをします これで保持サイクルと 強力または循環参照を 二つ削除できます
次は ヒープ領域とメモリの 回収漏れにつき説明します
ヒープ領域とは アプリケーションが動的に メモリの割り当てと解放を 繰り返せる領域です ヒープ領域のメモリの 回収漏れは メモリの 割り当てが増え続け 解放されないままの 領域が発生する状態です ヒープ領域の メモリの回収漏れの 対策として 確保された必要でない 領域の解放をします ヒープ領域で 確保している容量を 把握するべきです 必要に応じ 領域の確保と 解放を繰り返し メモリ管理をして下さい メモリ管理をする事で 予想以上の容量が 消費された際のAppの クラッシュを防ぎます
ミールプランナーAppの XCTestが不合格となった 領域のメモリの回収漏れを 詳しく見ていきましょう メモリの使用量については ”vmmap -summary”を 実行して”pre”と ”post”のmemgraphの メモリの容量が 表示されるレポートを 確認します
メモリの使用量は ”pre”のmemgraphでは 112メガバイトです ”post”のmemgraphでは 125メガバイトなので イテレーション前後で 13メガバイトの差です
下記には 各領域の メモリの使用量が 表示されています
ヒープ領域の メモリの回収漏れを 疑うので全ての オブジェクトが含まれる ”MALLOC_”の領域から 確認していきます
先程のTanujaの説明では メモリの使用量はダーティ メモリ+圧縮メモリです ここの”スワップ”ツールは ”圧縮”と同じ意味です このコラムで確認したい データ量は”ダーティ”と ”スワップ”の値だけです
安の定 ”MALLOC_LARGE”の 領域におよそ 13メガバイトのダーティ メモリが確認できます メモリの回収漏れの データとほぼ同量の 値なので詮索する 必要があります 13メガバイトの メモリの回収漏れの 原因を調査 していきます まず”heap -diffFrom”を ”post”のmemgraphで 実行します
コマンドラインに”pre”と ”post”のデータを プロンプトに追加します すると ”pre”ではなく ”post”memgraphだけの オブジェクトが 表示されます
上記に13メガバイトの 新しいオブジェクトが ”post"memgraphで 確認できます 下記は
ヒープ領域をオブジェクト クラスに割り当てたものです 各クラスの オブジェクトの個数と その個数に値する メモリバイトの合計数が 表示されています すぐに確認できるのは 13メガバイトは ”非オブジェクト”の 値だという事です Swiftでは 動的に確保された mallocバイトを示します この類のメモリの容量の 調査は少々注意が 必要ですが 特定のツールを 使用し詮索していきましょう まず非オブジェクトの参照 (アドレス)を確保します
”heap --addresses”を コマンドラインで実行します
次に500キロバイト以下の メモリの容量の 非オブジェクトを 表示するように設定します
なるほど ここに表示されている 非オブジェクトは およそ13メガバイトなので 調査する必要がありますね 表示されている 非オブジェクトの参照で メモリの使用量の 原因を見ていきます この時点でいくつか 調査に選択肢があります 状況によっては 全ての 選択肢には利点があるので 一つ一つを簡単に 説明します
この非オブジェクトの参照に ”leaks --traceTree”を 実行するのが第一選択肢です
参照のツリーのオブジェクト リストが表示されます この選択肢は memgraphで Malloc StackやMSLの属性が 確認できない状況で オブジェクトの メモリ使用量を 調べたい時に有利です Swiftとは異なり XCTestの memgraphに MSLの実装が 自動的に 設定されない状況で このツールを使用して下さい
関連のクラスをツリー リストでハイライトしました 問題の非オブジェクトは mealDataの ”MKTCustomMealPlanner CollectionViewCell”に 関連すると思われます ”leaks --referenceTree” コマンドも実行できます
結果 App全てのメモリ 使用量が 参照されたオブジェクトの トップダウンツリーで 表示され メモリ割り当ての 調査に役立ちます Appの メモリの割り当てが 確認できる 便利なツールです メモリの回収漏れの その原因の オブジェクトを 特定したい時に 使用したいツールです ”--groupByType”の コマンドライン引数を 指定すると類似した 要素ごとにファイルを 縮小することで確認が 容易になります
多くの場合 参照ツリーの 単一ノードに 大きいメモリの回収漏れが 確認できるので 詮索をする際に 有利です
関連のある オブジェクトを ハイライト表示します ここに ”-traceTree”の 設定との際と同じメモリの 回収漏れの”mealData” クラスがあります 表示では ”mealData”に 13メガバイトの メモリの割り当てが 確認できます このオブジェクトの 割り当てを詮索します Swiftのmemgraphでの MSLの実装をしコマンドの ”malloc_history- fullStacks”を実行します
ヒープ領域から 大きな非オブジェクトの アドレスパスをコマンド ラインに表示します
結果 その非オブジェクトの コールスタック割り当てが 表示されます MSLの実装できる時と オブジェクトの アドレス指定ができる時に 使用すると有利なツールです
コマンドライン3の ”saveMeal”関数に ”mealData”クラスの 割り当てが表示されてます ここで Xcodeの方を 確認しましょう View controllerの カスタムセルで”saveMeal” 関数の表示があります これがメモリリークです 生データのバッファを ここに割り当て ”mealData”クラスで ラッピングします バッファとしての割り当ては データ入力とディスクに 保存するためです ディスクに保存した後は このバッファは 必要ありません しかし なぜ解放されないのか?
”mealData”はクラス なので クラスの インスタンスとして 存在する以上は 参照は解放されません なので どのセルでも ”saveMeal”を 選択すると 大きなバッファが 確保されます 結果的に 複数のミールプランでかなり の量のメモリを消費します
この状態の修正方法とは? ”saveMeal”関数で ”mealData”をクラス内に 定義をする選択肢が ありますが 他のクラスでも 使用されているため このツールは使えません もう一つの選択肢は ”mealData”をディスクに データ入力し 保存した後 ”nil”に設定します Swiftの場合 オブジェクトの参照解放 処理を終えた時点で 自動的にバッファも 解放し バッファからの メモリリークも防げます
最後の説明は フラグメンテーション管理
iOSのページの 簡単な説明から入ります ページとは固定された サイズの不分割な メモリ領域にプロセス 機能が与えられます
この不分割な メモリ領域のため ページの 一部分だけに 書き込まれたプロセスで ほとんどのメモリが 使用されなてない ページも全て ダーティとして扱われます
ダーティページのメモリが 100%使用不可能な際に フラグメンテーションが 発生します この状況につき いくつかの事例をあげます まず連続した空白の ページから始めます
プロセス実行により 空白のページに データが割り当てられ ダーティになります
同じプロセス実行で オブジェクトの割り当て 解放もされ ”フリーメモリ”の 箇所も実現します しかし ページに他の 割り当てもあるので 空のメモリがありながら ページがダーティとなります
このフリーメモリの空き スロットは今からの 割り当ての対象になります 右のボックスは 空きメモリが必要な 大きな割り当てです 残念ながらこの割り当ては 既存のフリーメモリの 空のスロットには 容量が大き過ぎます 全ての空きスロットの 合計容量は大き目の 割り当てに十分ですが フリーメモリの箇所が連続 してないので利用できません
このため図の 右側の新しい ダーティページに 割り当てられ 既存のフリーメモリは 有効利用できません 空のスロットの フリーメモリは 使用できないままの フラグメンテーションです
フラグメンテーションを 減らす最も良い方法とは 同様のライフタイムの オブジェクトの割り当てを 特定の箇所に配置します こうすれば割り当ての 解放が同時に行われ 割り当てに必要な フリーメモリは 連続した領域に 確保できます
次の 事例では 手動でクラスに 割り当てた 全ての”my object”を 同時に解放します しかし コマンド書き込みを誤り 同様のオブジェクトを 特定の箇所に割り当てず 他の割り当ても既存します
ここでオブジェクトの 割り付けを解放すると 空のメモリのスロットが 4か所できますが 他の 割り当てがあるので連続 した領域のメモリと違います 結果はフラグメンテーション 50%とダーティ ページが4個です 好ましくありません
今度は”my object”の 割り当てを全て一か所に コマンドに書き込めば? 結果はページ2個に割り当て サイズを縮小できました オブジェクト割り当てを 解放すると空白のページが 2個になり 空きメモリが増え ダーティページも2個で0% のフラグメンテーションです フラグメンテーションは メモリの容量増加の原因です ダーティページの4個の フラグメンテーション50% がページ2個で半減しました しかし状態により フラグメンテーションが 必要な場合もあります 目安として フラグメンテーションは 25%以下が理想です
”autorelease pools”で フラグメンテーションを 減らせます ”autorelease pool”の メソッドのルールに従って 登録された割り当ての オブジェクトを解放します ”autorelease pool”で 全て同様のライフタイムの オブジェクトを 設定したいからです
フラグメンテーションは 全てのプロセスにおいて 生じるメモリの問題ですが 特に長時間のプロセスは アドレス領域の割り当てや 割り当ての解放が 多いので断片化が 生じやすいです 例えば長時間動作する Extensionを使用するAppは フラグメンテーションを プロセスで 確認するべきです
フラグメンテーションの 工程の簡単な確認のため ”vmmap -summary”を実行 下記の表示され値に スクロールします
このセクションはmalloc メモリ割り当て領域です 各領域には異なるタイプの 割り当てが表示してあります ”DefaultMallocZone” だけを通常は確認するのが 初期設定でヒープ割り当てが この領域に全て表示されます
しかし このmemgraphは MSLの実行が可能なので ”MallocStackLoggingLite Zone”の領域を確認します MSLの実行が可能である 限りは この特定の領域に ヒープが割り当てられます
カラム名が”% FRAG”の データは各malloc領域の フラグメンテーションによる リークの値を表示してます 表示されてる値で 大きなものもありますが 今 集中するのは”Malloc StackLoggingLiteZone”領域
理由は ”MallocStack LoggingLiteZone”領域には ダーティメモリが最も多く 割り当てられてるからです 合計量5メガバイトの内の 4.3メガバイト割り当てです なので 今回は他の領域を 確認しなくていいのです
カラム名で ”dirty+swap frag size” のデータは各malloc領域で フラグメンテーションによる メモリ漏れの値が 表示されてます
断片化でおよそ800Kの メモリ漏れが発生してます 多量のメモリリークに 見えますが 多少の フラグメンテーションは 避けられません なので25%以下の フラグメンテーションなら 多少のメモリ漏れの 発生は許せます
”MallocStackLogging LiteZone”を確認すると フラグメンテーションは 19%です 先ほど説明した通り 今の値は25%以下なので 許せる範囲です
フラグメンテーションの 問題が発生した場合は ツールの”Allocations” トラックを使用できます
とりわけ ”Allocations List”の 表示で興味あるのは 領域のオブジェクトの 確保または 削除状況です
フラグメンテーションに関し 解放されたオブジェクトで 空のメモリスロットに なる一方 割り当てが 残ったオブジェクトで 同じページが ダーティとして扱われます 両条件を調査することで フラグメンテーションの メモリ漏れの原因の 特定が可能です
これら開発者向けの ツールについての詳細は WWDC 2019の ”Instrumentsの概要”を 参考にして下さい
ヒープ領域のメモリ回収 漏れとリークの修正 それと フラグメンテーション問題 がない事が確認されたので XCTestを再度実行します
素晴らしい XCTestの合格で メモリの 使用量の問題は解決しました 今までメモリリークの検出と 原因を確認する工程の 説明を自身のAppで 実行できるように これから 内容の復習をしましょう Appに新機能を 搭載する際はメモリ管理と 提供されたメトリックで パフォーマンス計測のための XCTestを作成して 各計測ベースライン値を設定 メモリリーク又は回収漏れを 検出し Ktraceとmemgraphの ファイルの収集した データを詮索してください
不合格のXCTestの memgraphsファイルを 確認し メモリの使用量の 原因を調査しましょう 最初に確認するべきが メモリリークの原因です Leaksツールを実行し MSLのバックトレース 機能を使用して リークの検出をしましょう リークでないのが確認 されたら今度はヒープ領域を 検索して下さい コマンドラインの ”vmmap -summary”でメモリ 要素がヒープにあるかを確認
原因がヒープにある際は ”heap -diffFrom”を使用 どのオブジェクトがリークの 原因かを特定する 原因の判断ができる場合は ”heap -addresses”を使用し アドレスを入手して下さい 参照ツリーの確認のために ”leaks --referenceTree” 割り当てのオブジェクトの アドレスを指定するため ”leaks -traceTree”又は ”malloc_history”を使用
上記ベストプラクティスを 把握したワークフローを 実行してください App作成の際は リークの 完全対応を怠らずに unsafeクラスを使う場合は 割り当てを 全て解放する様 心がけてください 保持サイクルの発生にも 気を付けましょう
ヒープ領域のメモリの 使用量を減らすために ヒープ縮小や ヒープメモリの確保や 解放を頻繁に行い 必要でないヒープの 割り当てを解放する 様にして下さい フラグメンテーションも ヒープ管理の上で忘れずに 同じライフタイムの オブジェクトをまとめて 配置する事でフリー メモリが確保できます これらベストプラクティスと XCTestのワークフローで アプリケーションのメモリ リークの検知 診断そして 修正に必要なノウハウを 習得した事と思います Tanujaと私に貴重な 時間を頂き有難うございます [打楽器音楽]
-
-
4:52 - Monitor memory performance with XCTests
// Monitor memory performance with XCTests func testSaveMeal() { let app = XCUIApplication() let options = XCTMeasureOptions() options.invocationOptions = [.manuallyStart] measure(metrics: [XCTMemoryMetric(application: app)], options: options) { app.launch() startMeasuring() app.cells.firstMatch.buttons["Save meal"].firstMatch.tap() let savedButton = app.cells.firstMatch.buttons["Saved"].firstMatch XCTAssertTrue(savedButton.waitForExistence(timeout: 30)) } }
-
-
特定のトピックをお探しの場合は、上にトピックを入力すると、関連するトピックにすばやく移動できます。
クエリの送信中にエラーが発生しました。インターネット接続を確認して、もう一度お試しください。