Upgrade to Pro — share decks privately, control downloads, hide ads and more …

メモリ不足との戦い〜大量データを扱うアプリでの実践例〜

Avatar for ああうえ ああうえ
September 20, 2025

 メモリ不足との戦い〜大量データを扱うアプリでの実践例〜

Avatar for ああうえ

ああうえ

September 20, 2025
Tweet

More Decks by ああうえ

Other Decks in Programming

Transcript

  1. • ϝϞϦ্Ͱ͸ඇѹॖ • ୯७ͳܭࢉྫ • 2000×2000px × 32bit(RGBA) × 200ϨΠϠʔ

    • ≈ 3.2GB ※࣮ࡍʹ͸ϨΠϠʔ಺ͷඞཁͳՕॴ͚ͩ֬อ͢ΔͷͰɺ͜Μͳʹଟ͘͸ͳ͍ • ͜ΕҎ֎ʹ΋ϛοϓϚοϓ΍৭ʑͳΩϟογϡͳͲ͕ଘࡏ  ϝϞϦෆ଍ͱͷઓ͍ʙେྔσʔλΛѻ͏ΞϓϦͰͷ࣮ફྫʙʛ͋͋͏͑ ϨΠϠʔͷ֬อϝϞϦʹ͍ͭͯ
  2. JetsamΠϕϯτΛ֬ೝ͢Δ • .ipsϑΝΠϧ(JSONܗࣜ) • largestProcessΛ֬ೝ͢Δ • ࣗ෼ͷΞϓϦͰ͋Ε͹ϝϞϦ࢖༻ʹ໰୊͕͋ΔՄೳੑ • reason: ऴྃͨ͠ཧ༝(per-process-limit,

    vm-pageshortage, …) • rpages: ֬อ͞Ε͍ͯͨϖʔδ਺ɻpageSizeΛֻ͚Δͱ࢖༻ྔʹ  ϝϞϦෆ଍ͱͷઓ͍ʙେྔσʔλΛѻ͏ΞϓϦͰͷ࣮ફྫʙʛ͋͋͏͑ iOSͷϝϞϦʹ͍ͭͯ஌Δ
  3. ϝϞϦϫʔχϯά(didReceiveMemoryWarning) • UIKit • didReceiveMemoryWarning • SwiftUI • didReceiveMemoryWarningNoti fi

    cation • AppDelegate • applicationDidReceiveMemoryWarning(_:)  ϝϞϦෆ଍ͱͷઓ͍ʙେྔσʔλΛѻ͏ΞϓϦͰͷ࣮ફྫʙʛ͋͋͏͑ iOSͷϝϞϦʹ͍ͭͯ஌Δ
  4. ϝϞϦϫʔχϯά(DispatchSource) • DispatchSourceMemoryPressure • normal / warning / critical •

    ෮چ࣌΋௨஌ͯ͘͠ΕΔ  ϝϞϦෆ଍ͱͷઓ͍ʙେྔσʔλΛѻ͏ΞϓϦͰͷ࣮ફྫʙʛ͋͋͏͑ dispatchSource = DispatchSource.makeMemoryPressureSource(eventMask: .all) dispatchSource.setEventHandler { switch dispatchSource.data { case .normal: ... case .warning: ... case .critical: ... } } dispatchSource.activate() iOSͷϝϞϦʹ͍ͭͯ஌Δ
  5. Memory Compression • iOS 7+ • iOSͰ͸Disk SwapͰ͸ͳ͘Memory CompressionΛ࠾༻ iPadOS

    16.1͔Β͸Virtual Memory Swap͕༗ޮͳ୺຤΋͋Δ • ࠷ۙΞΫηεͷͳ͍DirtyͳϖʔδΛѹॖ  ϝϞϦෆ଍ͱͷઓ͍ʙେྔσʔλΛѻ͏ΞϓϦͰͷ࣮ફྫʙʛ͋͋͏͑ iOSͷϝϞϦʹ͍ͭͯ஌Δ
  6. ϝϞϦෆ଍Ξϥʔτ͕දࣔ͞Εͳ͍໰୊Λਪଌ • ϝϞϦϫʔχϯά͕ਖ਼͘͠ड͚औΕ͍ͯͳ͍? • ࠷ॳͷ࣮૷͸didReceiveMemoryWarningΛ࢖༻ • ݹ͍୺຤Ͱ͸ൃՐ͠΍͍͢ • ৽͠Ίͷ୺຤Ͱ͸ൃՐͤͣʹڧ੍ऴྃ·Ͱߦ͘͜ͱ΋? •

    DispatchSourceMemoryPressureͳΒݕ஌Ͱ͖Δ? • Apple Silicon൛iPadͳͲɺ৽͍͠୺຤ͩͱى͜Δ?  ϝϞϦෆ଍ͱͷઓ͍ʙେྔσʔλΛѻ͏ΞϓϦͰͷ࣮ફྫʙʛ͋͋͏͑ ϝϞϦϫʔχϯάͷਂ۷Γ
  7. ϝϞϦϫʔχϯάΛड͚औΔ࣮૷͕ѱ͍ͷ͔? • didReceiveMemoryWarning → DispatchSourceMemoryPressure • ࡉ͔͍ΠϕϯτΛड͚औΔΑ͏ʹͨ͠ΒมΘΔͷ͔? • ݁࿦: ಺෦࣮૷͕ಉ͡ͳͨΊɺड͚औΔλΠϛϯά͸มΘΒͳ͍

    • > Dispatch Sources • > UIKit further exposes handlers for App developers. See Responding to Low Memory Warnings. https://github.com/apple-oss-distributions/xnu/blob/rel/xnu-11417/doc/vm/memorystatus_notify.md • ͦ΋ͦ΋ɺυΩϡϝϯτʹ͸ϕετΤϑΥʔτͰൃՐ͢Δͱ͋Δ  ϝϞϦෆ଍ͱͷઓ͍ʙେྔσʔλΛѻ͏ΞϓϦͰͷ࣮ફྫʙʛ͋͋͏͑ ϝϞϦϫʔχϯάͷਂ۷Γ
  8. Jetsamͷ൑ఆ • ͍͔ͭ͘ͷஈ֊΍৚݅Ͱͷ൑ఆ͕͋Δ • https://github.com/apple-oss-distributions/xnu/blob/rel/ xnu-11417/doc/vm/memorystatus_kills.md • 13छྨ΄Ͳ • MEMORY_PERPROCESSLIMIT

    • ϓϩηεͰར༻Ͱ͖ΔϝϞϦ্ݶ஋Λ࢖ͬͨ൑ఆ • ௒͑Δͱଈkill͞ΕΔ  ϝϞϦෆ଍ͱͷઓ͍ʙେྔσʔλΛѻ͏ΞϓϦͰͷ࣮ફྫʙʛ͋͋͏͑ ϝϞϦϫʔχϯάͷਂ۷Γ
  9. ϝϞϦϫʔχϯάͷᮢ஋(warning)  ϝϞϦෆ଍ͱͷઓ͍ʙେྔσʔλΛѻ͏ΞϓϦͰͷ࣮ફྫʙʛ͋͋͏͑ • AVAILABLE_NON_COMPRESSED_MEMORY • AVAILABLE_MEMORY • γεςϜͰར༻Մೳͳ૯ϝϞϦϖʔδ਺ •

    AVAILABLE_NON_COMPRESSED_MEMORY + compressed • compressed: γεςϜͰѹॖ͞Ε͍ͯΔϖʔδ਺(ѹॖޙ) • VM_PAGE_COMPRESSOR_COMPACT_THRESHOLD ϝϞϦϫʔχϯάͷਂ۷Γ
  10. ϝϞϦϫʔχϯάͷᮢ஋(warning)  ϝϞϦෆ଍ͱͷઓ͍ʙେྔσʔλΛѻ͏ΞϓϦͰͷ࣮ફྫʙʛ͋͋͏͑ boolean_t VM_PRESSURE_NORMAL_TO_WARNING(void) { if (!VM_CONFIG_COMPRESSOR_IS_ACTIVE) { ...

    } else { return (AVAILABLE_NON_COMPRESSED_MEMORY < VM_PAGE_COMPRESSOR_COMPACT_THRESHOLD) ? 1 : 0; } } vm_pageout.c ϝϞϦϫʔχϯάͷਂ۷Γ
  11. ϝϞϦϫʔχϯάͷᮢ஋(warning)  ϝϞϦෆ଍ͱͷઓ͍ʙେྔσʔλΛѻ͏ΞϓϦͰͷ࣮ફྫʙʛ͋͋͏͑ boolean_t VM_PRESSURE_NORMAL_TO_WARNING(void) { if (!VM_CONFIG_COMPRESSOR_IS_ACTIVE) { ...

    } else { return (AVAILABLE_NON_COMPRESSED_MEMORY < VM_PAGE_COMPRESSOR_COMPACT_THRESHOLD) ? 1 : 0; } } AVAILABLE_MEMORY - compressed vm_pageout.c ϝϞϦϫʔχϯάͷਂ۷Γ
  12. ϝϞϦϫʔχϯάͷᮢ஋(warning)  ϝϞϦෆ଍ͱͷઓ͍ʙେྔσʔλΛѻ͏ΞϓϦͰͷ࣮ફྫʙʛ͋͋͏͑ boolean_t VM_PRESSURE_NORMAL_TO_WARNING(void) { if (!VM_CONFIG_COMPRESSOR_IS_ACTIVE) { ...

    } else { return (AVAILABLE_NON_COMPRESSED_MEMORY < VM_PAGE_COMPRESSOR_COMPACT_THRESHOLD) ? 1 : 0; } } 0.5 * AVAILABLE_MEMORY vm_pageout.c ϝϞϦϫʔχϯάͷਂ۷Γ
  13. ϝϞϦϫʔχϯάͷ൑ఆ  ϝϞϦෆ଍ͱͷઓ͍ʙେྔσʔλΛѻ͏ΞϓϦͰͷ࣮ફྫʙʛ͋͋͏͑ • AVL_MEMORY - compressed < AVL_MEMORY *

    0.5 • compressed > AVL_MEMORY * 0.5 • γεςϜͰར༻Մೳͳ૯ϝϞϦͷ50%ΑΓcompressed͕ଟ͍ͱ ൃՐ ϝϞϦϫʔχϯάͷਂ۷Γ
  14. ୺຤ͷRAMͱϝϞϦϫʔχϯά  ϝϞϦෆ଍ͱͷઓ͍ʙେྔσʔλΛѻ͏ΞϓϦͰͷ࣮ફྫʙʛ͋͋͏͑ • compressed > AVL_MEMORY * 0.5 •

    RAM͕େ͖͍ͱAVL_MEMORYͷ஋΋େ͖͍ • ૬ରతʹWarning൑ఆ͞ΕͮΒ͍ ϝϞϦϫʔχϯάͷਂ۷Γ
  15. os_proc_available_memory • iOS 13+ • ϓϩηεͰར༻Ͱ͖Δ࢒ΓͷϝϞϦྔΛऔಘ • σϑΥϧτͷঢ়ଶͰiPhone 16 ProͰ3GB΄Ͳ

    • 0ʹͳΔͱJetsamʹΑͬͯڧ੍ऴྃ • (γϛϡϨʔλʔͰ͸ৗʹ0Λฦ͢)  ϝϞϦෆ଍ͱͷઓ͍ʙେྔσʔλΛѻ͏ΞϓϦͰͷ࣮ફྫʙʛ͋͋͏͑
  16. Extended Virtual Addressing Entitlement • iOS 14+ • ΞϓϦʹׂΓ౰ͯΒΕΔԾ૝ΞυϨεۭ͕ؒ޿͕Δ 

    ϝϞϦෆ଍ͱͷઓ͍ʙେྔσʔλΛѻ͏ΞϓϦͰͷ࣮ફྫʙʛ͋͋͏͑ ແޮ࣌ ༗ޮ࣌ iPhone 16 ProͰͷ஋ Ծ૝ΞυϨεۭؒͷෆ଍ʹରॲ͢Δ
  17. Tips: Firebase CrashlyticsͷRAMۭ͖༰ྔ • Tips: Firebase Crashlyticsͷʮσʔλ > RAMۭ͖༰ྔʯ͸γες Ϝͷ෺ཧϝϞϦͷۭ͖༰ྔ

    • ΞϓϦ಺Ͱ͸vm_statistics64ͷfree_count * page_sizeͰऔಘ • ීஈϝϞϦ࢖༻ྔͷগͳ͍ΞϓϦͰ͸ϝϞϦϦʔΫ͕ਪଌՄೳ • ଟ͘ͷϝϞϦΛ࢖͏ΞϓϦͰ͸͋·Γҙຯͷͳ͍஋ • RAMۭ͖༰ྔ͕গͳͯ͘΋εϫοϓ΍ѹॖͰղܾ͞ΕΔՄೳੑ ͕͋ΔͨΊ  ϝϞϦෆ଍ͱͷઓ͍ʙେྔσʔλΛѻ͏ΞϓϦͰͷ࣮ફྫʙʛ͋͋͏͑
  18. ࢀߟ • Responding to low-memory warnings - Apple Developer •

    apple-oss-distributions/xnu • iOS Memory Deep Dive - WWDC18 • Detect and diagnose memory issues - WWDC21 • Analyze heap memory - WWDC24  ϝϞϦෆ଍ͱͷઓ͍ʙେྔσʔλΛѻ͏ΞϓϦͰͷ࣮ફྫʙʛ͋͋͏͑