Memory Graph: apa itu, graf objek dan mendeteksi referensi siklik

Penulis: IT Sectr Diterbitkan: 2026-05-07 Waktu membaca: 10 mnt

Memory Graph — alat visual Xcode Debug Navigator yang menampilkan graf objek di memori RAM aplikasi dengan referensi timbal baliknya. Tidak seperti heap dump, Memory Graph tidak hanya menampilkan daftar objek, tetapi graf referensi terarah, di mana setiap simpul adalah objek dan setiap tepi adalah referensi (strong, weak, unowned). Menurut Apple WWDC 2018, alat ini memungkinkan deteksi visual retain cycles dan kebocoran memori dalam hitungan detik, tanpa perlu menganalisis data mentah heap dump.

Poin Utama

  • Memory Graph — graf visual objek di memori Xcode, menunjukkan referensi antar objek secara real-time.
  • Retain cycle terdeteksi melalui kontur tertutup dalam graf — dua atau lebih objek saling merujuk dengan referensi kuat.
  • Backtrace untuk setiap tepi graf menunjukkan di mana dan kapan referensi ditetapkan, memudahkan pencarian sumber kebocoran.
  • Pemfilteran berdasarkan nama kelas dan tipe referensi (strong/weak) memungkinkan isolasi cepat objek bermasalah.
  • Integrasi dengan Memory Report di Xcode memungkinkan pelacakan perubahan konsumsi memori secara real-time.

Apa itu Memory Graph dan cara kerjanya

Memory Graph — adalah komponen Xcode Debug Navigator (muncul di Xcode 10, WWDC 2018) yang membangun graf terarah dari semua objek di memori proses yang di-debug. Setiap simpul graf adalah instance kelas (Objective-C atau Swift), setiap tepi adalah referensi ke objek lain. Warna tepi menunjukkan tipe referensi: biru — strong, hijau — weak, abu-abu — unowned. Graf dibangun berdasarkan data LLDB dan Objective-C runtime, oleh karena itu agar berfungsi dengan benar, aplikasi harus dikompilasi dalam konfigurasi Debug dengan simbol diaktifkan.

Prinsip kerja: ketika aplikasi dijeda di breakpoint, Xcode melalui LLDB meminta runtime untuk semua objek hidup dan referensinya. LLDB menggunakan objc_getClassList dan iterasi melalui region alokasi untuk membangun graf lengkap. Pada ARM64 (Apple Silicon) tambahan menggunakan perangkat keras untuk pelacakan alokasi tanpa perlambatan. Waktu pembangunan graf tergantung pada ukuran heap: untuk aplikasi iOS tipikal (50–200 MB) graf dibangun dalam 1–3 detik.

Menurut Apple, Memory Graph adalah satu-satunya alat yang dapat memvisualisasikan retain cycles tanpa modifikasi kode atau penambahan instrumentasi. Tidak seperti Instruments Leaks, Memory Graph bekerja secara real-time di dalam Xcode dan tidak memerlukan peluncuran profiler terpisah. Ini menjadikannya alat pilihan pertama untuk diagnosis cepat kebocoran memori dalam proses pengembangan.

Apa perbedaan Memory Graph dengan heap dump

Heap dump memberikan tabel semua objek dengan angka (shallow size, retained size) — optimal untuk analisis kuantitatif. Memory Graph memberikan gambaran visual koneksi — optimal untuk mencari referensi siklik. Alat-alat saling melengkapi: pertama Memory Graph untuk deteksi cepat retain cycles, kemudian heap dump melalui Instruments Allocations untuk pengukuran retained size yang akurat. Menurut pengalaman objc.io, kombinasi dua metode mencakup 95% skenario kebocoran memori.

Mendeteksi retain cycles dengan Memory Graph

Retain cycle — situasi ketika dua atau lebih objek saling mempertahankan dengan referensi kuat, membentuk kontur tertutup. ARC tidak dapat melepaskan kontur seperti itu, karena retain count setiap objek tidak pernah mencapai nol. Contoh klasik: ViewController dan View, di mana View memiliki strong reference ke closure yang menangkap self (ViewController). Memory Graph menampilkan kontur tersebut dalam bentuk cincin (siklus), menyorotnya untuk identifikasi cepat.

Ketika Xcode mendeteksi retain cycle, ia menyorotnya dengan kontur oranye dan menampilkan peringatan di Debug Navigator. Dengan mengklik siklus, Anda melihat rantai referensi yang membentuk kontur tertutup. Pengembang tinggal menentukan tepi kuat mana yang harus lemah — biasanya ini adalah referensi dari objek anak ke induk (misalnya, delegate atau closure).

swift
class ViewController: UIViewController {
    let service = DataService()

    override func viewDidLoad() {
        super.viewDidLoad()
        // ❌ Siklus retain: ViewController → layanan → 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
    }
}

Di Memory Graph Anda akan melihat segitiga: ViewController → DataService → closure → ViewController. Solusinya — penangkapan self secara lemah: [weak self]. Setelah perbaikan, Memory Graph akan menunjukkan tepi hijau dari closure ke ViewController, dan retain cycle akan hilang.

swift
// Kode yang diperbaiki — penangkapan self secara lemah
service.fetchData { [weak self] data in
    guard let self else { return }
    self.updateUI(data)
}

Antarmuka Memory Graph Debugger di Xcode

Antarmuka Memory Graph Debugger terdiri dari tiga panel: kiri — daftar semua objek hidup (dikelompokkan berdasarkan kelas) dengan jumlah instance; tengah — graf visual dengan simpul yang dapat diseret; kanan — inspektor objek atau tepi yang dipilih. Di daftar objek ditampilkan: ikon kelas, jumlah instance di memori, total retained size dan persentase dari seluruh heap. Pemfilteran berdasarkan nama kelas mendukung ekspresi reguler.

Navigasi graf

Simpul graf dapat diseret untuk meningkatkan keterbacaan. Klik ganda pada simpul membuka informasi detail tentang objek: semua propertinya dengan tipe dan nilai, tumpukan panggilan (backtrace) untuk setiap properti dan riwayat retain/release. Backtrace — fitur kunci: ini menunjukkan baris kode mana yang tepat menetapkan referensi ke objek. Ini memungkinkan menemukan sumber kebocoran tanpa meninjau seluruh kode secara manual.

Untuk graf kompleks, Xcode menyediakan tata letak otomatis melalui Layout → Hierarchical (hierarkis) atau Cluster (klaster). Tata letak hierarkis menempatkan objek root di atas, objek anak di bawah, memudahkan pencarian rantai. Tata letak klaster mengelompokkan objek terkait dalam klaster, yang berguna ketika graf berisi beberapa grup terisolasi. Menurut Apple, untuk sebagian besar aplikasi disarankan tata letak hierarkis — intuitif dan membutuhkan lebih sedikit waktu untuk analisis visual.

lldb
// Perintah LLDB yang digunakan Memory Graph di balik layar
(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

Analisis graf: menemukan dan memperbaiki kebocoran

Pendekatan sistematis untuk analisis Memory Graph mencakup beberapa tahap. Tahap 1: jalankan aplikasi, lakukan skenario yang berpotensi menyebabkan kebocoran (buka/tutup layar, lakukan permintaan jaringan). Tahap 2: tekan tombol Memory Graph di Debug Navigator — Xcode akan membangun graf. Tahap 3: periksa peringatan oranye retain cycles di panel kiri. Tahap 4: untuk objek mencurigakan gunakan opsi Show only cycles — hanya simpul yang termasuk dalam referensi siklik yang akan ditampilkan.

Menggunakan backtrace untuk menemukan sumber

Ketika retain cycle ditemukan, klik tepi siklus dan buka panel inspektor. Di bagian Backtrace ditunjukkan tumpukan panggilan pada saat referensi ini ditetapkan. Misalnya, jika tepi mengarah dari closure ke self, backtrace akan menunjukkan di metode mana dan di baris kode mana closure dibuat. Ini menghilangkan kebutuhan untuk menebak — Anda langsung melihat titik pembuatan referensi bermasalah. Menurut WWDC Labs, analisis backtrace mengurangi waktu diagnosis retain cycle dari 15–20 menit menjadi 2–3 menit.

swift
class ProfileViewController: UIViewController {
    var profileView: ProfileView!

    override func viewDidLoad() {
        super.viewDidLoad()
        profileView = ProfileView()
        // Memory Graph akan menunjukkan retain cycle di sini
        profileView.onTap = { [unowned self] in
            // ⚠️ unowned dapat menyebabkan crash saat nil self
            self.navigateToDetail()
        }
    }

    func navigateToDetail() { }
}

// ✅ Benar: [weak self] + guard let self
profileView.onTap = { [weak self] in
    guard let self else { return }
    self.navigateToDetail()
}

Memfilter objek yang tidak perlu

Memory Graph dapat menampilkan ribuan objek, mempersulit pencarian. Gunakan filter di panel kiri: masukkan nama kelas (misalnya, ProfileViewController) untuk menampilkan hanya instance kelas tersebut. Kemudian pilih instance yang seharusnya sudah dilepaskan (jika layar ditutup tetapi objek tetap ada). Terapkan Show Reachable From — hanya referensi yang relevan untuk objek ini yang akan ditampilkan, menyembunyikan sisa graf.

Tips praktis menggunakan Memory Graph

Pengembang berpengalaman menggunakan Memory Graph tidak hanya untuk mencari kebocoran, tetapi juga untuk kontrol memori proaktif. Periksa Memory Graph setelah setiap perubahan arsitektur besar — penambahan delegate baru, closure atau langganan ke NotificationCenter. Cukup jalankan skenario tipikal dan pastikan objek dilepaskan dengan benar dan retain cycles tidak ada. Ini memakan waktu 2–3 menit, tetapi mencegah berjam-jam debugging di kemudian hari.

Kombinasi dengan Memory Report

Memory Report di Xcode (tab Debug Navigator) menunjukkan grafik konsumsi memori secara real-time. Gunakan bersama dengan Memory Graph: buka Memory Graph saat konsumsi meningkat tajam. Misalnya, saat menggulir daftar panjang dengan sel yang memuat gambar, Memory Graph akan menunjukkan objek mana yang dibuat dan mana yang dilepaskan. Jika jumlah objek meningkat tanpa penurunan — ini potensi kebocoran, terlihat sebelum menyebabkan crash. Menurut Apple, kombinasi Memory Graph + Memory Report adalah workflow yang direkomendasikan untuk semua pengembang iOS mulai dari Xcode 12.

objective-c
// Contoh kebocoran di Objective-C melalui delegasi
@interface DownloadManager : NSObject
@property (strong) id delegate; // ❌ Harus weak!
@end

@implementation DownloadManager
// Memory Graph akan menunjukkan retain cycle:
// ViewController → DownloadManager.delegate → ViewController
@end

// Perbaikan: weak property
@property (weak) id delegate;

Profil closure

Berikan perhatian khusus pada closures — sumber retain cycles paling umum di Swift. Saat menangkap self di dalam closure yang disimpan sebagai properti objek, terbentuk siklus klasik. Memory Graph menampilkan ini sebagai closure (simpul dengan simbol {}), terhubung dengan tepi biru ke objek yang ditangkap. Periksa secara teratur semua closures, terutama yang digunakan dalam panggilan asinkron, GCD, Combine dan SwiftUI. Menurut statistik Point-Free, 90% kebocoran di proyek Swift terkait dengan closures yang menangkap self.

Pertanyaan yang Sering Diajukan

Apakah Memory Graph hanya berfungsi untuk Objective-C atau juga untuk Swift?

Memory Graph berfungsi untuk kedua bahasa, karena menggunakan Objective-C runtime. Objek Swift yang kompatibel dengan ObjC (pewaris NSObject, ditandai dengan @objc) ditampilkan sepenuhnya. Struktur dan kelas Swift murni tanpa jembatan ObjC terlihat terbatas.

Mengapa Memory Graph tidak menampilkan beberapa objek?

Objek harus terdaftar di Objective-C runtime. Swift value types (struct, enum) tidak ditampilkan. Pastikan kelas mewarisi NSObject atau menggunakan atribut @objc untuk visibilitas di Memory Graph.

Bagaimana menafsirkan warna tepi dalam graf?

Biru — strong reference, mempertahankan objek. Hijau — weak reference, tidak mempengaruhi siklus hidup. Abu-abu — unowned reference. Retain cycle hanya terbentuk dari tepi biru.

Apakah Memory Graph memperlambat aplikasi?

Pembangunan graf menjeda aplikasi selama 1–3 detik dan dapat meningkatkan konsumsi memori Xcode sementara sebesar 200–500 MB. Aplikasi itu sendiri tidak melambat, karena inspeksi terjadi saat jeda di breakpoint.

Bisakah Memory Graph diekspor untuk analisis?

Xcode tidak mendukung ekspor langsung graf. Gunakan tangkapan layar untuk dokumentasi atau skrip lldb heap.find_variable untuk ekstraksi data secara terprogram. Untuk analisis detail gunakan Instruments Allocations dengan heap dump.

Ringkasan

  • Memory Graph — alat visual Xcode untuk menampilkan graf objek di memori dengan referensinya.
  • Retain cycle ditampilkan sebagai kontur tertutup dari tepi biru (strong) — Xcode menyorotnya dengan oranye.
  • Backtrace untuk setiap tepi graf menunjukkan lokasi tepat dalam kode di mana referensi bermasalah dibuat.
  • Pemfilteran berdasarkan kelas dan tipe referensi memungkinkan mengisolasi kebocoran dalam graf dengan ribuan objek.
  • Closures — sumber utama retain cycles di Swift, Memory Graph menampilkannya sebagai simpul {}.
  • Weak dan unowned — solusi untuk memutus siklus, tetapi weak lebih disukai karena keamanan saat nil.
  • Pemeriksaan rutin Memory Graph setelah perubahan arsitektur mencegah regresi memori dalam proyek.

Kami akan mengembangkan aplikasi seluler turnkey

IT Sectr membuat aplikasi iOS dan Android untuk startup dan bisnis sejak 2017. Kami akan memberi saran dan mengusulkan solusi terbaik.

Diskusikan proyek

Baca juga