Memory Graph: bu nima, obyektlar grafi va tsiklik havolalarni aniqlash

Muallif: IT Sectr Nashr etilgan: 2026-05-07 O'qish vaqti: 10 daq

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 xotirasidagi obyektlarning vizual grafi, obyektlar orasidagi havolalarni real vaqtda ko'rsatadi.
  • Retain cycle grafdagi yopiq kontur bo'yicha aniqlanadi — ikki yoki undan ortiq obyektlar bir-biriga kuchli havolalar bilan bog'lanadi.
  • Backtrace grafning har bir qirrasi uchun havola qayerda va qachon o'rnatilganini ko'rsatadi, oqish manbasini topishni osonlashtiradi.
  • Filtrlash sinf nomi va havola turi (strong/weak) bo'yicha muammoli obyektlarni tezda ajratish imkonini beradi.
  • Integratsiya Xcode-dagi Memory Report bilan xotira iste'moli o'zgarishini real vaqtda kuzatish imkonini beradi.

Memory Graph nima va u qanday ishlaydi

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.

Memory Graph ning heap dump dan farqi

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.

Memory Graph yordamida retain cycles ni aniqlash

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).

swift
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.

swift
// Tuzatilgan kod — self ni zaif tutish
service.fetchData { [weak self] data in
    guard let self else { return }
    self.updateUI(data)
}

Xcode-da Memory Graph Debugger interfeysi

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 bo'ylab navigatsiya

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.

lldb
// 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

Graf tahlili: oqishlarni topish va bartaraf etish

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.

Manbani topish uchun backtrace dan foydalanish

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.

swift
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()
}

Keraksiz obyektlarni filtrlash

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.

Memory Graph dan foydalanish bo'yicha amaliy maslahatlar

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 bilan kombinatsiya

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
// 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;

Closure larni profillash

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 faqat Objective-C uchun ishlaydimi yoki Swift uchun ham?

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.

Nega Memory Graph ba'zi obyektlarni ko'rsatmaydi?

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.

Grafdagi qirra ranglarini qanday izohlash kerak?

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.

Memory Graph ilovani sekinlashtiradimi?

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.

Memory Graph ni tahlil uchun eksport qilish mumkinmi?

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

  • Memory Graph — Xcode ning xotiradagi obyektlar grafigini havolalari bilan ko'rsatadigan vizual vositasi.
  • Retain cycle ko'k (strong) qirralardan yopiq kontur sifatida ko'rsatiladi — Xcode uni to'q sariq rangda ajratib ko'rsatadi.
  • Backtrace grafning har bir qirrasi uchun muammoli havola yaratilgan aniq kod joyini ko'rsatadi.
  • Filtrlash sinflar va havola turlari bo'yicha minglab obyektli grafda oqishlarni ajratish imkonini beradi.
  • Closure lar Swift da retain cycles ning asosiy manbai, Memory Graph ularni {} tugunlari sifatida ko'rsatadi.
  • Weak va unowned tsiklni uzish uchun yechimlar, lekin nil dagi xavfsizlik tufayli weak afzal.
  • Muntazam Memory Graph tekshiruvi arxitektura o'zgarishlaridan so'ng loyihada xotira regressiyasining oldini oladi.

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.

Loyihani muhokama qilish

Shuningdek o'qing