RORK LABEN
MAX — Rork MaxはReact NativeではなくネイティブSwiftアプリを生成し、iPhone・iPad・Apple Watch・Apple TV・Vision Pro・iMessageに対応しますNATIVE — Rork MaxではAR/LiDARスキャン・Metalによる3Dゲーム・ウィジェット・Dynamic Islandなどネイティブ機能を利用できますAPPLE — HealthKit・HomeKit・NFC・App Clips・オンデバイスCore MLといったAppleの高度な機能にもアクセスできますRN — 標準のRorkはReact Native(Expo)でiOSとAndroidを単一プロンプトから生成しますPRICE — 無料で始められ、有料プランは月額$25から利用できますGROWTH — Rorkは月間訪問743,000超・成長率85%に達し、$15Mの資金を調達しましたMAX — Rork MaxはReact NativeではなくネイティブSwiftアプリを生成し、iPhone・iPad・Apple Watch・Apple TV・Vision Pro・iMessageに対応しますNATIVE — Rork MaxではAR/LiDARスキャン・Metalによる3Dゲーム・ウィジェット・Dynamic Islandなどネイティブ機能を利用できますAPPLE — HealthKit・HomeKit・NFC・App Clips・オンデバイスCore MLといったAppleの高度な機能にもアクセスできますRN — 標準のRorkはReact Native(Expo)でiOSとAndroidを単一プロンプトから生成しますPRICE — 無料で始められ、有料プランは月額$25から利用できますGROWTH — Rorkは月間訪問743,000超・成長率85%に達し、$15Mの資金を調達しました
記事一覧/開発ツール
開発ツール/2026-07-10上級

クラッシュとして記録されない強制終了 — Rork アプリの JetsamEvent を読む

Crashlytics には何も出ていないのにレビューで「勝手に閉じる」と書かれる。その多くはメモリ超過による OS からの強制終了です。JetsamEvent レポートの読み方と、画像中心アプリのメモリ上限を実測から設計する手順をまとめます。

Rork496Rork Max219メモリ3iOS106個人開発179

プレミアム記事

App Store のレビュー欄に「開いてしばらくすると勝手に閉じます」と書かれていたのに、Crashlytics のダッシュボードは静まり返ったまま、という時期がありました。壁紙アプリの一つで、しかも再現手順が「たくさんスクロールする」としか書かれていない。手元の実機ではどれだけ触っても落ちません。

原因が分かったのは、実機の「設定 > プライバシーとセキュリティ > 解析および改善 > 解析データ」を開いて、JetsamEvent-2026-… という名前のファイルが並んでいるのを見つけたときでした。クラッシュではなく、OS がメモリ不足を理由にアプリを終了させていた。だからクラッシュレポータには何も届いていなかったのです。

Rork や Rork Max で作ったアプリでも、事情はまったく同じです。生成されたコードがどれだけ整っていても、iOS がプロセスに与えるメモリの上限は変わりません。むしろ生成コードは画像やリストを気前よく扱うことが多く、この上限に触れやすい傾向があると私自身は感じています。

Jetsam はクラッシュではない、という前提

iOS には Jetsam という仕組みがあります。システム全体のメモリが逼迫したとき、あるいは単一プロセスが device ごとの上限を超えたとき、カーネルがそのプロセスに SIGKILL を送って回収します。

SIGKILL はハンドルできません。ここが重要な点です。Crashlytics も Sentry も、シグナルハンドラや例外ハンドラを仕込んでクラッシュを捕まえます。捕まえる隙を与えずに殺されるので、クラッシュとして記録されない。App Store Connect の「クラッシュ」指標にも現れません。

代わりに、Xcode Organizer では Crashes ではなく Disk Writes / Hangs とは別枠の、MXAppExitMetriccumulativeMemoryResourceLimitExitCount として集計されます。ここを見ていない個人開発者は多いはずです。私も見ていませんでした。

終了の種類クラッシュレポータに届くか確認場所
例外・シグナル(SIGSEGV 等)届くCrashlytics / Organizer > Crashes
メモリ超過(Jetsam)届かない実機の解析データ / MetricKit
ウォッチドッグ(起動遅延)一部届くOrganizer > Hangs、0x8badf00d
バックグラウンドでの回収届かない正常動作。対処不要

最下段が地味に大切です。段階的な解放設計そのものはiOS のメモリ逼迫に応じて 5 段階で解放する設計で整理しました。バックグラウンドに回ったアプリが後で回収されるのは、iOS の正常な振る舞いです。すべての JetsamEvent を潰そうとすると、無駄な作業に沈みます。潰すべきは フォアグラウンドで殺されたもの だけです。

JetsamEvent レポートを読む

実機の解析データからファイルを取り出します。共有ボタンから AirDrop や Files に出せます。中身は JSON 風のテキストです。

まず 1 行目付近のヘッダを見ます。

{"bug_type":"298","timestamp":"2026-06-14 21:03:11.42 +0900","os_version":"iPhone OS 26.1 (23B82)",
 "incident_id":"…","pageSize":16384,"memoryStatus":{"compressorSize":98213,"memoryPages":{"active":41022,
 "free":1290,"wired":38310}}}

bug_type が 298 なら Jetsam です。そして pageSize が 16384、つまり 16 KB。ここを 4096 だと思い込むと、以降の換算が 4 倍ずれます。A14 以降の端末は 16 KB ページなので、必ずこのフィールドを読んでください。

次に、殺された当人を探します。レポート本体は states の配列で、各プロセスがこう並びます。

{"uuid":"…","states":["frontmost"],"killDelta":0,"genCount":0,"age":133,"purgeable":0,
 "fds":124,"coalition":312,"rpages":86214,"reason":"per-process-limit",
 "name":"WallpaperApp","cpuTime":41.2,"idleDelta":0}

読むべきは 3 つです。

  1. statesfrontmost が含まれるか — 含まれていれば、ユーザーの目の前で消えたということです
  2. reasonper-process-limit は自分のアプリが上限を超えた、vm-pageshortage はシステム全体の逼迫に巻き込まれた
  3. rpages — 常駐ページ数。MB への換算は rpages × pageSize ÷ 1024 ÷ 1024

この例なら 86214 × 16384 ÷ 1048576 ≒ 1,347 MB。iPhone SE(第3世代)で 1,384 MB の上限に触れて殺された、という読み方になります。

面倒なので、一括で換算するスクリプトを置いておきます。

#!/usr/bin/env bash
# jetsam-summary.sh — 解析データから取り出した .ips をまとめて要約する
# 使い方: ./jetsam-summary.sh ~/Downloads/JetsamEvent-*.ips
for f in "$@"; do
  python3 - "$f" <<'PY'
import json, sys, re
raw = open(sys.argv[1], encoding="utf-8").read()
# 先頭ヘッダ行と本体が連結されているので、最初の } で分割する
head, body = raw.split("\n", 1) if "\n" in raw else (raw, "{}")
page = json.loads(head).get("pageSize", 4096)
ts   = json.loads(head).get("timestamp", "?")
for m in re.finditer(r'\{"uuid".*?\}', body):
    p = json.loads(m.group(0))
    mb = p.get("rpages", 0) * page / 1048576
    if p.get("reason") in ("per-process-limit", "vm-pageshortage") and mb > 100:
        front = "FRONTMOST" if "frontmost" in p.get("states", []) else "background"
        print(f'{ts}  {p["name"]:<22} {mb:8.1f} MB  {p["reason"]:<18} {front}')
PY
done

私はこれを 3 週間分のレポート 41 件に流し、フォアグラウンドで per-process-limit に触れていたのが 12 件、うち 11 件が同じ画面(グリッド表示の壁紙一覧)だと分かりました。ここまで来れば、あとは実装の問題です。

ここまでお読みいただきありがとうございます。

この記事の続きを読む

この先には、実装コードやベンチマーク結果など、実務でお役に立てる内容をご用意しています。このサイトは広告を掲載しておらず、サーバーや開発にかかる費用はメンバーの皆様のご支援で成り立っています。もしお役に立てていましたら、ご支援いただけますと大変ありがたいです。

この記事で得られること
JetsamEvent レポートの rpages を MB に換算し、どのプロセスが何 MB で殺されたかを特定する手順
os_proc_available_memory() で残メモリを実測し、iPhone SE 実機で 1,384 MB / 2,099 MB の上限差を確認したログ
画像キャッシュを totalCostLimit で残メモリの 25% に自動追従させる Swift / React Native 両方の実装
Stripe による安全な決済 · いつでもキャンセル可能

この記事を購入する

この先の内容をすべてお読みいただけます。一度のご購入で、いつでも何度でもアクセスできます。このサイトは広告を掲載しておらず、皆さまのご支援がサーバー費用などの運営を支えています。

または
メンバーシップなら全記事が読み放題 →
シェア

お読みいただきありがとうございます

Rork Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • コピー&ペーストで使える実装コード付き
  • 毎日新しい上級ガイドを追加
  • ¥580/月 または ¥1,480 の永久アクセス
メンバーシップを見る →

関連記事

開発ツール2026-06-21
Xcode を介さない公開で抜け落ちる事前確認を、自分で取り戻す
Rork Max の2クリック公開は Xcode の Organizer を通らないぶん、用途文言・バージョン・Bundle ID の取りこぼしに気づきにくくなります。提出前に自分でできる自己点検の手順を、生成物の読み方つきで具体的に整理しました。
開発ツール2026-06-14
アプリを開かなくても更新される、を Expo で実際に届ける — Background Task の現実的な設計
Rork が生成する Expo アプリで『毎朝コンテンツが更新される』体験を作ろうとすると、iOS のバックグラウンド実行は思ったほど律儀に動きません。expo-background-task の最小実装と、実行されない前提で破綻しない設計をまとめました。
開発ツール2026-05-25
Rork iOSアプリのメモリプレッシャー対策 — 壁紙アプリ運用で磨いた5段階解放アーキテクチャ
Rork経由でビルドしたiOSアプリのメモリプレッシャー対策を、5段階解放という考え方で整理しました。壁紙アプリ群を12年運用してきた中で見えた優先順位と、Instrumentsでの計測手順を実装込みで紹介します。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →