Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Valentin Simonov
Field Engineer
Unity Technologies
val@unity3d.com
valyard
Understanding Memory on iOS
• Partly applicable to other platforms
• But needs testing
No need to take pictures
Detailed doc at the end*
* yes, you will have to sit through the entire presentation
How much memory does my game take?
- How much memory does my game take?
- What kind of memory?
• Physical/Resident Memory
• Graphics Memory
• Virtual Memory
...
Physical Memory (RAM)
• The total amount of memory on-chip
• You can’t have more*
* But Android users can... until it is m...
Virtual Memory (VM)
• iOS apps don’t work with Physical Memory directly, they work with Virtual Memory
• App’s private add...
Resident Memory
• An app can allocate a block of memory in Virtual Memory but not use it (”reserve”)
• The app has to modi...
Clean Memory and Dirty Memory
• Clean Memory — read-only pages of Resident Memory which iOS can remove and reload
• Dirty ...
Clean Memory and Dirty Memory
• Memory allocated for the following data is Clean (iOS can reload this from disk):
• App’s ...
Graphics Memory (VRAM)
• iOS uses a Unified Memory Architecture — GPU and CPU share Physical Memory
• Graphics Driver allo...
Malloc Heap
• A region of VM where the app can allocate memory using malloc and calloc functions
• This is where Unity all...
Swapped (compressed) Memory
• iOS doesn’t have a page file and can’t dump rarely used Virtual Memory pages to disk
• But i...
Native (Unity) Memory
• Unity is a C++ engine with a .NET Virtual Machine
• Native Memory — part of Malloc Heap (VM Region...
Native Plugins
• Native plugins do their own allocations in Malloc Heap
• Their code binaries are “Clean”
PhysicalMemory
A...
Mono Heap
• A part of Native Memory allocated for the needs of the .NET Virtual Machine
• Contains all managed C# allocati...
Mono Heap
Native Memory
Managed Objects
Unused Mono Heap
ImaginationReality
• Mono Heap is not a large contiguous region o...
iOS Memory Management
• iOS is a multitasking OS
• Each app works with its own Virtual Memory address space mapped to Phys...
iOS Memory Management
• When the amount of free Physical Memory gets low,
iOS starts trying to reduce memory pressure:
1. ...
Minimize the Size of Dirty Memory!
• Measure the app’s Dirty Memory and see if it grows over time,
• Reduce the amount of ...
Minimize the Size of Dirty Memory!
• Reasonable limits of Dirty Memory:
• 180Mb for 512Mb devices,
• 360Mb for 1Gb devices...
Tools
Unity Profiler
Unity Profiler | Simple View
• Mono (used) — the size of Mono Heap
(the total sum of pink and green blocks)
• Mono (total)...
Unity Profiler | Detailed View
• Shows named objects in Native Memory and which objects reference them
• Assets folder sho...
MemoryProfiler
MemoryProfiler | BitBucket
• Shows a combination of:
• Assets (Virtual Memory),
• Assets (GPU)
• Managed objects (Mono),
•...
MemoryProfiler | BitBucket
https://bitbucket.org/Unity-Technologies/memoryprofiler
MemoryProfiler
Array of strings
An obje...
MemoryProfiler Extension
MemoryProfiler Extension | Github
• We can see Mono Heap
• Total size: 256KB + 256KB + 128KB = 640KB
• Used: 86.5KB.
https...
Xcode Debug View
• Available in Xcode Debug Navigator view
• Shows if the app is doing OK memory wise
• Seems to be approx...
VM Tracker Instrument
VM Tracker
(1) Total for the app
1. Total memory consumption:
a. The app has allocated 1GB of VM
b. It has committed 351MB (186+165)
...
(3) Graphics Driver
1. *All* — all allocations
2. *Dirty* — all Dirty allocations
3. IOKit — Graphics Driver
4. VM_ALLOCAT...
Allocations Instrument
Allocations Instrument
Loading Thread
A Scene is loading
FMOD Initializes
Unity Allocates
Memory for the Audio
Total Alloc...
Allocations Instrument
An Asset Bundle is being loaded
A Class metadata is initialized
Allocations
Allocations
Example | Parsing JSON
1. Load and parse a 350KB JSON file
2. GC.Collect()
3. 8x GC.Collect()
iPhone 6, iOS 11.3
Unity 201...
Step 0: Initial State
Different tools showing the same data:
1. Unity Profiler shows 0.5MB committed but 364KB used
2. VM ...
Step 0: Initial State
Allocations Instrument shows call stack for all allocations:
1. The first 4 allocations were done du...
Step 0: Initial State
Block 1
• Two blocks of Mono Heap
• Total size of Managed objects: 58KB
• Notice the fragmentation
B...
Step 1: Parsing JSON
1. Notice how expensive the operation was
2. Total memory allocated during the process: 5.6MB
3. But ...
Step 1: Parsing JSON
• Allocations Instrument shows new allocations
• The same allocated blocks can be seen in VM Tracker
...
Step 1: Parsing JSON
Look at the sizes of the new allocs:
• 1.75MB ~= 2 x 960KB
• 960KB ~= 2 x 528KB
• 528KB ~= 2 x 256KB
...
MemoryProfiler Ext
Mono Heap
Committed: 4.0MB
Heap Size: 3.3MB
Used: 1.0MB
Step 2: GC.Collect()
1. Mono Heap size, was: 3.0MB, now: 2.0MB
2. Allocated Mono memory — no change
3. Virtual Machine sti...
Step 3: GC.Collect() x8
1. 8x GC.Collect() calls is expensive
2. Unity Profiler shows that the reserved Mono Heap size has...
Step 3: GC.Collect() x8
1. Two committed blocks were released
2. They still reserve Virtual Memory but don’t contribute to...
Understanding Memory on iOS
http://bit.ly/ios-memory
Detailed document with much more info.
Valentin Simonov
Field Enginee...
【Unite Tokyo 2018】その最適化、本当に最適ですか!? ~正しい最適化を行うためのテクニック~
Upcoming SlideShare
Loading in …5
×

【Unite Tokyo 2018】その最適化、本当に最適ですか!? ~正しい最適化を行うためのテクニック~

3,468 views

Published on

講演者:Valentin Simonov(Unity Technologies)

こんな人におすすめ
・中級・上級の開発者
・最適化のテクニックを学びたい方
・Unityでの最適化ツールの使用方法を習得した経験豊富なプログラマー

受講者が得られる知見
・プロファイリングと最適化を開始する前に知っておきたいプラットフォーム別の問題解決方法
・ 最適化の例
・ Unityのシステムの内部的な仕組み

Published in: Technology

【Unite Tokyo 2018】その最適化、本当に最適ですか!? ~正しい最適化を行うためのテクニック~

  1. 1. Valentin Simonov Field Engineer Unity Technologies val@unity3d.com valyard
  2. 2. Understanding Memory on iOS • Partly applicable to other platforms • But needs testing
  3. 3. No need to take pictures Detailed doc at the end* * yes, you will have to sit through the entire presentation
  4. 4. How much memory does my game take?
  5. 5. - How much memory does my game take? - What kind of memory? • Physical/Resident Memory • Graphics Memory • Virtual Memory • Malloc Heap • Dirty Memory • Native Memory • Mono Heap
  6. 6. Physical Memory (RAM) • The total amount of memory on-chip • You can’t have more* * But Android users can... until it is mysteriously gone Physical Memory
  7. 7. Virtual Memory (VM) • iOS apps don’t work with Physical Memory directly, they work with Virtual Memory • App’s private address space • Divided into Pages (4KB or 16KB) • Pages are mapped to Physical Memory by the OS PhysicalMemory Allocated Virtual Memory AvailableAddressSpace
  8. 8. Resident Memory • An app can allocate a block of memory in Virtual Memory but not use it (”reserve”) • The app has to modify the allocated VM for the OS to map it to PM (”commit”) • Resident Memory is the total amount of Physical Memory used by the app at any moment PhysicalMemory Resident Memory AvailableAddressSpace reserved (not part of RM) committed (part of RM)
  9. 9. Clean Memory and Dirty Memory • Clean Memory — read-only pages of Resident Memory which iOS can remove and reload • Dirty Memory — everything else in Resident Memory • Apps can share Clean Memory pages (like, system frameworks) PhysicalMemory AvailableAddressSpace Clean Dirty
  10. 10. Clean Memory and Dirty Memory • Memory allocated for the following data is Clean (iOS can reload this from disk): • App’s binaries, static code segments, • memory-mapped files, • System frameworks and dynamic libraries, etc. PhysicalMemory AvailableAddressSpace Binaries Dirty
  11. 11. Graphics Memory (VRAM) • iOS uses a Unified Memory Architecture — GPU and CPU share Physical Memory • Graphics Driver allocates Virtual Memory for its resources • Most of this is Resident and Dirty PhysicalMemory AvailableAddressSpace Graphics Memory Binaries Dirty
  12. 12. Malloc Heap • A region of VM where the app can allocate memory using malloc and calloc functions • This is where Unity allocates all memory for its needs • The maximum size is unknown, but seems to be 2x Physical Memory PhysicalMemory Malloc Heap AvailableAddressSpace Graphics Memory Binaries
  13. 13. Swapped (compressed) Memory • iOS doesn’t have a page file and can’t dump rarely used Virtual Memory pages to disk • But it can compress them and store in some other region of Physical Memory • SCM is a compressed part of the app’s Dirty Memory • The algorithm is unknown, but iOS usually tries to compress as much as it can PhysicalMemory Clean Not Compressed Dirty Memory Compressed Dirty Memory
  14. 14. Native (Unity) Memory • Unity is a C++ engine with a .NET Virtual Machine • Native Memory — part of Malloc Heap (VM Region) used for all Unity’s allocations • All asset data is in Native Memory, exposed to C# as lightweight wrappers PhysicalMemory AvailableAddressSpace Native Memory Graphics Memory Binaries
  15. 15. Native Plugins • Native plugins do their own allocations in Malloc Heap • Their code binaries are “Clean” PhysicalMemory AvailableAddressSpace Native Memory Graphics Memory Binaries Native Plugins
  16. 16. Mono Heap • A part of Native Memory allocated for the needs of the .NET Virtual Machine • Contains all managed C# allocations, maintained by Garbage Collector PhysicalMemory AvailableAddressSpace Native Memory Graphics Memory Binaries Native Plugins Mono Heap
  17. 17. Mono Heap Native Memory Managed Objects Unused Mono Heap ImaginationReality • Mono Heap is not a large contiguous region of Native Memory • It is allocated in blocks to store objects of similar size • There can be allocated, committed but unused blocks • If a block is still unused after 8 Garbage Collection passes, its Physical Memory will be returned to the system (decommitted) Block Block Almost empty block Block Allocated but unused block Allocated but unused block
  18. 18. iOS Memory Management • iOS is a multitasking OS • Each app works with its own Virtual Memory address space mapped to Physical Memory
  19. 19. iOS Memory Management • When the amount of free Physical Memory gets low, iOS starts trying to reduce memory pressure: 1. Removes Clean Memory pages (they can be safely reloaded later) 2. If the app takes too much Dirty Memory, iOS sends memory warnings 3. If the app fails to free resources, iOS terminates it • We don’t know the details about this algorithm • Sometimes an app can allocate more, sometimes less
  20. 20. Minimize the Size of Dirty Memory! • Measure the app’s Dirty Memory and see if it grows over time, • Reduce the amount of objects contributing to Dirty Memory, • Note: some data can be compressed better. PhysicalMemory AvailableAddressSpace Native Memory Graphics Memory Binaries Native Plugins Mono Heap Dirty Memory
  21. 21. Minimize the Size of Dirty Memory! • Reasonable limits of Dirty Memory: • 180Mb for 512Mb devices, • 360Mb for 1Gb devices, • 1.2Gb for 2Gb devices. • ... but, iOS can still kill the app ¯¥_(ツ)_/¯
  22. 22. Tools
  23. 23. Unity Profiler
  24. 24. Unity Profiler | Simple View • Mono (used) — the size of Mono Heap (the total sum of pink and green blocks) • Mono (total) — the total committed memory for Mono Heap (the total size of pink, green and blue blocks) • GfxDriver — the total size of 2D textures, excluding render targets • FMOD — the total size of memory requested by FMOD (audio) • Other values should be ignored: • Total doesn’t include the size of game binaries, libs, frameworks, native plugins • GfxDriver doesn’t include a lot of other allocations done by the Graphics Driver • The Profiler only sees allocations done by Unity code Unity Profiler
  25. 25. Unity Profiler | Detailed View • Shows named objects in Native Memory and which objects reference them • Assets folder shows how much Native Memory assets take Unity Profiler Unity Profiler • Many large sounds • Probably duplicated textures (have identical names)
  26. 26. MemoryProfiler
  27. 27. MemoryProfiler | BitBucket • Shows a combination of: • Assets (Virtual Memory), • Assets (GPU) • Managed objects (Mono), • Object references • Easy to see relative sizes https://bitbucket.org/Unity-Technologies/memoryprofiler MemoryProfiler
  28. 28. MemoryProfiler | BitBucket https://bitbucket.org/Unity-Technologies/memoryprofiler MemoryProfiler Array of strings An object in Mono Heap with its content listed
  29. 29. MemoryProfiler Extension
  30. 30. MemoryProfiler Extension | Github • We can see Mono Heap • Total size: 256KB + 256KB + 128KB = 640KB • Used: 86.5KB. https://github.com/robertoardila/support-unity-memoryprofiler MemoryProfiler Ext Block 1 Block 2 Block 3
  31. 31. Xcode Debug View • Available in Xcode Debug Navigator view • Shows if the app is doing OK memory wise • Seems to be approximately Dirty Memory + Swapped Memory • For detailed profiling should use Instruments
  32. 32. VM Tracker Instrument
  33. 33. VM Tracker
  34. 34. (1) Total for the app 1. Total memory consumption: a. The app has allocated 1GB of VM b. It has committed 351MB (186+165) c. But iOS has swapped 165MB d. Now it is 186MB Physical Memory e. 118MB of which is Dirty Memory 2. Binaries, libs and frameworks a. They take Resident Memory b. But they are not Dirty (i.e., Clean) (2) Binaries and libs (a)(c)(d) (e) (a) (b) VM Tracker
  35. 35. (3) Graphics Driver 1. *All* — all allocations 2. *Dirty* — all Dirty allocations 3. IOKit — Graphics Driver 4. VM_ALLOCATE — Mono allocations + Heap 5. MALLOC_* — Malloc Heap 6. __TEXT + __LINKEDIT — app and lib binaries 7. __DATA — writable executable data 8. Perf. tool data — Instruments overhead (4) Mono Heap VM Tracker
  36. 36. Allocations Instrument
  37. 37. Allocations Instrument Loading Thread A Scene is loading FMOD Initializes Unity Allocates Memory for the Audio Total Allocated Memory Allocations
  38. 38. Allocations Instrument An Asset Bundle is being loaded A Class metadata is initialized Allocations Allocations
  39. 39. Example | Parsing JSON 1. Load and parse a 350KB JSON file 2. GC.Collect() 3. 8x GC.Collect() iPhone 6, iOS 11.3 Unity 2018.1
  40. 40. Step 0: Initial State Different tools showing the same data: 1. Unity Profiler shows 0.5MB committed but 364KB used 2. VM Tracker shows 1.25MB of allocations (in 3 blocks), 0.5MB of which is Mono Heap 3. Allocations Instrument shows each separate allocation (note the Category) Unity Profiler VM Tracker Allocations
  41. 41. Step 0: Initial State Allocations Instrument shows call stack for all allocations: 1. The first 4 allocations were done during IL2CPP initialization 2. The 5th allocation was done when creating a managed object (1) (2) Allocations
  42. 42. Step 0: Initial State Block 1 • Two blocks of Mono Heap • Total size of Managed objects: 58KB • Notice the fragmentation Block 2 Unity Profiler MemoryProfiler Ext
  43. 43. Step 1: Parsing JSON 1. Notice how expensive the operation was 2. Total memory allocated during the process: 5.6MB 3. But Mono Heap size hasn’t increased that much 4. Because GC has run a few times to reclaim it (1) CPU Time (2) Total Memory Allocated (3) Mono Heap Size(4) Garbage Collector Unity Profiler Unity Profiler
  44. 44. Step 1: Parsing JSON • Allocations Instrument shows new allocations • The same allocated blocks can be seen in VM Tracker • Notice that allocations (2) and (3) are in the same block • Mono Heap takes ~4MB of Virtual Memory, all of it is Dirty (1) (1) (2) (2+3) (3) (4) (4) Allocations VM Tracker
  45. 45. Step 1: Parsing JSON Look at the sizes of the new allocs: • 1.75MB ~= 2 x 960KB • 960KB ~= 2 x 528KB • 528KB ~= 2 x 256KB • 256KB StringBuilder is expanding its reserved memory Allocations
  46. 46. MemoryProfiler Ext Mono Heap Committed: 4.0MB Heap Size: 3.3MB Used: 1.0MB
  47. 47. Step 2: GC.Collect() 1. Mono Heap size, was: 3.0MB, now: 2.0MB 2. Allocated Mono memory — no change 3. Virtual Machine still has the same amount of committed memory 4. Some of it is compressed (1) Mono Heap Size Unity Profiler VM Tracker (2) Mono (3) Mono (4) Compressed
  48. 48. Step 3: GC.Collect() x8 1. 8x GC.Collect() calls is expensive 2. Unity Profiler shows that the reserved Mono Heap size has decreased Unity Profiler Unity Profiler (2) Mono Reserved (1) CPU time spent
  49. 49. Step 3: GC.Collect() x8 1. Two committed blocks were released 2. They still reserve Virtual Memory but don’t contribute to Resident Memory (1) Released blocks VM Tracker Allocations (2) Blocks are not Resident
  50. 50. Understanding Memory on iOS http://bit.ly/ios-memory Detailed document with much more info. Valentin Simonov Field Engineer Unity Technologies val@unity3d.com valyard

×