Memory Graph — Xcode Debug Navigator-ning vizual vositasi bo'lib, ilovaning operativ xotirasidagi obyektlar grafigini ularning o'zaro havolalari bilan ko'rsatadi. Heap dump-dan farqli o'laroq, Memory Graph shunchaki obyektlar ro'yxatini emas, balki har bir tugun obyekt va har bir qirra havola (strong, weak, unowned) bo'lgan yo'naltirilgan havolalar grafigini ko'rsatadi. Apple WWDC 2018 ma'lumotlariga ko'ra, vosita bir necha soniya ichida retain cycles va xotira oqishlarini vizual ravishda aniqlash imkonini beradi, heap dumpning xom ma'lumotlarini tahlil qilish talab qilinmaydi.
Asosiy fikrlar
Memory Graph — Xcode Debug Navigator komponenti (Xcode 10, WWDC 2018 da paydo bo'lgan) bo'lib, disk raskadrovka qilinayotgan jarayon xotirasidagi barcha obyektlarning yo'naltirilgan grafigini quradi. Grafning har bir tuguni sinf namunasi (Objective-C yoki Swift), har bir qirrasi boshqa obyektga havoladir. Qirraning rangi havola turini ko'rsatadi: ko'k — strong, yashil — weak, kulrang — unowned. Graf LLDB va Objective-C runtime ma'lumotlari asosida quriladi, shuning uchun to'g'ri ishlashi uchun ilova Debug konfiguratsiyasida belgilar yoqilgan holda kompilyatsiya qilinishi kerak.
Ishlash prinsipi: ilova breakpoint da to'xtatilganda, Xcode LLDB orqali runtime dan barcha tirik obyektlar va ularning havolalarini so'raydi. LLDB to'liq grafni qurish uchun objc_getClassList va ajratish hududlari bo'ylab iteratsiyadan foydalanadi. ARM64 (Apple Silicon) da sekinlashmasdan ajratishni kuzatish uchun qo'shimcha apparat vositalaridan foydalaniladi. Grafni qurish vaqti heap hajmiga bog'liq: odatdagi iOS ilovasi (50–200 MB) uchun graf 1–3 soniyada quriladi.
Apple ma'lumotlariga ko'ra, Memory Graph kodni o'zgartirmasdan yoki instrumentatsiya qo'shmasdan retain cycles ni vizuallashtira oladigan yagona vositadir. Instruments Leaks dan farqli o'laroq, Memory Graph Xcode ichida real vaqtda ishlaydi va profilerni alohida ishga tushirishni talab qilmaydi. Bu uni ishlab chiqish jarayonida xotira oqishlarini tez diagnostika qilish uchun birinchi tanlov vositasiga aylantiradi.
Heap dump raqamlar bilan (shallow size, retained size) barcha obyektlarning jadvalini beradi — miqdoriy tahlil uchun optimaldir. Memory Graph bog'lanishlarning vizual tasvirini beradi — tsiklik havolalarni qidirish uchun optimaldir. Vositalar bir-birini to'ldiradi: avval Memory Graph tez retain cycles aniqlash uchun, so'ngra Instruments Allocations orqali heap dump aniq retained size o'lchash uchun. objc.io tajribasiga ko'ra, ikki usulning kombinatsiyasi xotira oqishi stsenariylarining 95% ini qamrab oladi.
Retain cycle — ikki yoki undan ortiq obyektlar bir-birini kuchli havolalar bilan ushlab, yopiq kontur hosil qiladigan holatdir. ARC bunday konturni bo'shata olmaydi, chunki har bir obyektning retain count si hech qachon nolga yetmaydi. Klassik misol: ViewController va View, bu yerda View closure ga strong reference ga ega va closure self (ViewController) ni tutadi. Memory Graph bunday konturlarni halqa (tsikl) shaklida ko'rsatadi, tez identifikatsiya qilish uchun ularni ajratib ko'rsatadi.
Xcode retain cycle ni aniqlaganida, uni to'q sariq kontur bilan ajratib ko'rsatadi va Debug Navigator da ogohlantirish ko'rsatadi. Tsiklga bosganingizda, yopiq konturni tashkil etuvchi havolalar zanjirini ko'rasiz. Dasturchiga qaysi kuchli qirra zaif bo'lishi kerakligini aniqlash qoladi — odatda bu bola obyektdan ota-ona obyektga havoladir (masalan, delegate yoki closure).
class ViewController: UIViewController {
let service = DataService()
override func viewDidLoad() {
super.viewDidLoad()
// ❌ Retain tsikli: ViewController → xizmat → closure → ViewController
service.fetchData { self.updateUI($0) }
}
func updateUI(_ data: Data) {}
}
class DataService {
var completion: ((Data) -> Void)?
func fetchData(handler: @escaping (Data) -> Void) {
self.completion = handler
}
}
Memory Graph da uchburchakni ko'rasiz: ViewController → DataService → closure → ViewController. Yechim — self ni zaif tutish: [weak self]. Tuzatishdan so'ng, Memory Graph closure dan ViewController ga yashil qirrani ko'rsatadi va retain cycle yo'qoladi.
// Tuzatilgan kod — self ni zaif tutish
service.fetchData { [weak self] data in
guard let self else { return }
self.updateUI(data)
}
Memory Graph Debugger interfeysi uch paneldan iborat: chap — barcha tirik obyektlarning (sinflar bo'yicha guruhlangan) ro'yxati namunalar soni bilan; markaz — sudraluvchi tugunli vizual graf; o'ng — tanlangan obyekt yoki qirraning inspektori. Obyekt ro'yxatida ko'rsatiladi: sinf ikonasi, xotiradagi namunalar soni, umumiy retained size va butun heap ga nisbatan foiz. Sinf nomi bo'yicha filtrlash muntazam ifodalarni qo'llab-quvvatlaydi.
Graf tugunlari o'qish qulayligini yaxshilash uchun sudralishi mumkin. Tugunga ikki marta bosish obyekt haqida batafsil ma'lumotni ochadi: turlari va qiymatlari bilan barcha xususiyatlari, har bir xususiyat uchun chaqiruv steki (backtrace) va retain/release tarixi. Backtrace — asosiy funksiya: obyektga havolani qaysi kod qatori o'rnatganligini ko'rsatadi. Bu butun kodni qo'lda ko'rib chiqmasdan oqish manbasini topish imkonini beradi.
Murakkab graflar uchun Xcode Layout → Hierarchical (ierarxik) yoki Cluster (klaster) orqali avtomatik joylashuvni ta'minlaydi. Ierarxik joylashuv ildiz obyektlarni tepada, bola obyektlarni pastda joylashtiradi, zanjirlarni qidirishni osonlashtiradi. Klaster joylashuv bog'liq obyektlarni klasterlarga guruhlaydi, bu graf bir nechta ajratilgan guruhlarni o'z ichiga olganida qulaydir. Apple ma'lumotlariga ko'ra, ko'pchilik ilovalar uchun ierarxik joylashuv tavsiya etiladi — intuitiv va vizual tahlilga kamroq vaqt talab qiladi.
// Memory Graph tomonidan ishlatiladigan LLDB buyruqlari
(lldb) script import lldb.macosx.heap
(lldb) script heap.find_variable("viewController")
0x600000c4b80: ViewController
(lldb) script heap.refs 0x600000c4b80
0x600000c4b80 -> 0x600003a4c00 (DataService)
ivar: _service, offset: 16
Memory Graph tahliliga tizimli yondashuv bir necha bosqichni o'z ichiga oladi. Bosqich 1: ilovani ishga tushiring, potentsial oqishga sabab bo'ladigan stsenariyni bajaring (ekranni oching/yoping, tarmoq so'rovini bajaring). Bosqich 2: Debug Navigator da Memory Graph tugmasini bosing — Xcode graf quradi. Bosqich 3: chap paneldagi to'q sariq retain cycles ogohlantirishlarini tekshiring. Bosqich 4: shubhali obyektlar uchun Show only cycles opsiyasidan foydalaning — faqat tsiklik havolalarga kiruvchi tugunlar ko'rsatiladi.
Retain cycle topilganda, tsikl qirrasini bosing va inspektor panelini oching. Backtrace bo'limida ushbu havola o'rnatilgan paytdagi chaqiruv steki ko'rsatilgan. Masalan, qirra closure dan self ga olib borsa, backtrace closure qaysi metodda va qaysi kod qatorida yaratilganini ko'rsatadi. Bu taxmin qilish zaruratini yo'q qiladi — muammoli havolaning yaratilish nuqtasini darhol ko'rasiz. WWDC Labs ma'lumotlariga ko'ra, backtrace tahlili retain cycle diagnostikasi vaqtini 15–20 daqiqadan 2–3 daqiqagacha qisqartiradi.
class ProfileViewController: UIViewController {
var profileView: ProfileView!
override func viewDidLoad() {
super.viewDidLoad()
profileView = ProfileView()
// Memory Graph retain tsiklini bu yerda ko'rsatadi
profileView.onTap = { [unowned self] in
// ⚠️ unowned nil self da crash ga sabab bo'lishi mumkin
self.navigateToDetail()
}
}
func navigateToDetail() { }
}
// ✅ To'g'ri: [weak self] + guard let self
profileView.onTap = { [weak self] in
guard let self else { return }
self.navigateToDetail()
}
Memory Graph minglab obyektlarni ko'rsatishi mumkin, qidirishni qiyinlashtiradi. Chap paneldagi filtrlardan foydalaning: sinf nomini kiriting (masalan, ProfileViewController), faqat shu sinf namunalarini ko'rsatish uchun. Keyin bo'shatilishi kerak bo'lgan namunani tanlang (agar ekran yopiq bo'lsa, lekin obyekt qolgan bo'lsa). Show Reachable From ni qo'llang — faqat ushbu obyekt uchun muhim bo'lgan havolalar ko'rsatiladi, grafning qolgan qismi yashiriladi.
Tajribali dasturchilar Memory Graph dan nafaqat oqishlarni qidirish, balki proaktiv xotira nazorati uchun ham foydalanadilar. Memory Graph ni tekshiring har bir katta arxitektura o'zgarishidan so'ng — yangi delegate, closure yoki NotificationCenter obunasi qo'shilganda. Oddiy stsenariyni bajarish va obyektlarning to'g'ri bo'shatilganligiga, retain cycles mavjud emasligiga ishonch hosil qilish kifoya. Bu 2–3 daqiqa vaqt oladi, lekin keyingi soatlab disk raskadrovka qilishning oldini oladi.
Memory Report Xcode da (Debug Navigator varag'i) real vaqtda xotira iste'moli grafigini ko'rsatadi. Memory Graph bilan birgalikda foydalaning: xotira iste'moli keskin oshganda Memory Graph ni oching. Masalan, rasmlarni yuklaydigan hujayralar bilan uzun ro'yxatni aylantirganda, Memory Graph qaysi obyektlar yaratilayotganini va qaysilari bo'shatilayotganini ko'rsatadi. Agar obyektlar soni kamaymasdan oshsa — bu potentsial oqish bo'lib, crash ga olib kelishidan oldin ko'rinadi. Apple ma'lumotlariga ko'ra, Memory Graph + Memory Report kombinatsiyasi Xcode 12 dan boshlab barcha iOS dasturchilari uchun tavsiya etilgan ish oqimidir.
// Objective-C da delegatsiya orqali oqish namunasi
@interface DownloadManager : NSObject
@property (strong) id delegate; // ❌ Weak bo'lishi kerak!
@end
@implementation DownloadManager
// Memory Graph retain tsiklini ko'rsatadi:
// ViewController → DownloadManager.delegate → ViewController
@end
// Tuzatish: weak property
@property (weak) id delegate;
Maxsus e'tiborni closures ga qarating — Swift da retain cycles ning eng keng tarqalgan manbai. Obyektning xususiyati sifatida saqlanadigan closure ichida self tutilganda klassik tsikl hosil bo'ladi. Memory Graph buni closure ( {} belgisi bilan tugun) sifatida ko'rsatadi, tutilgan obyektlar bilan ko'k qirralar bilan bog'lanadi. Barcha closures larni muntazam tekshiring, ayniqsa asinxron chaqiruvlarda, GCD, Combine va SwiftUI da ishlatiladiganlarni. Point-Free statistikasiga ko'ra, Swift loyihalarida oqishlarning 90% self ni tutuvchi closures bilan bog'liq.
Tez-tez beriladigan savollar
Memory Graph ikkala til uchun ishlaydi, chunki Objective-C runtime dan foydalanadi. ObjC bilan mos Swift obyektlari (NSObject vorislari, @objc bilan belgilangan) to'liq ko'rsatiladi. ObjC ko'prigisiz sof Swift strukturalari va sinflari cheklangan ko'rinadi.
Obyektlar Objective-C runtime da ro'yxatdan o'tgan bo'lishi kerak. Swift value types (struct, enum) ko'rsatilmaydi. Sinf NSObject dan voris ekanligiga yoki Memory Graph da ko'rinish uchun @objc atributidan foydalanilganligiga ishonch hosil qiling.
Ko'k — strong reference, obyektni ushlab turadi. Yashil — weak reference, hayotiy tsiklga ta'sir qilmaydi. Kulrang — unowned reference. Retain cycle faqat ko'k qirralardan hosil bo'ladi.
Grafni qurish ilovani 1–3 soniyaga to'xtatadi va Xcode xotira iste'molini vaqtincha 200–500 MB ga oshirishi mumkin. Ilovaning o'zi sekinlashmaydi, chunki tekshirish breakpoint dagi pauza vaqtida amalga oshiriladi.
Xcode grafni to'g'ridan-to'g'ri eksport qilishni qo'llab-quvvatlamaydi. Hujjatlashtirish uchun ekran tasvirini yoki ma'lumotlarni dasturiy olish uchun lldb skripti heap.find_variable dan foydalaning. Batafsil tahlil uchun Instruments Allocations dan heap dump bilan foydalaning.
Xulosa
{} tugunlari sifatida ko'rsatadi.Biz kalit topshirig'i bilan mobil ilovani ishlab chiqamiz
IT Sectr 2017-yildan beri startaplar va korxonalar uchun iOS va Android ilovalarini yaratadi. Biz sizga maslahat beramiz va eng yaxshi yechimni taklif qilamiz.