Strong Reference (referensi kuat): apa itu, mekanisme kerja dan ARC

Penulis: IT Sectr Diterbitkan: 2026-03-30 Waktu membaca: 9 mnt

Strong Reference (referensi kuat) — adalah mekanisme standar manajemen memori di mana objek tetap berada di memori selama setidaknya ada satu referensi aktif yang menunjuk ke sana. Berbeda dengan referensi lemah, referensi kuat meningkatkan penghitung referensi objek dan mencegah pelepasan otomatisnya. Menurut Apple Developer Documentation, ARC secara otomatis mengelola masa hidup objek di Swift dan Objective-C. Memahami cara kerja referensi kuat sangat penting untuk mencegah kebocoran memori dan dependensi siklik dalam aplikasi mobile.

Poin utama

  • Strong Reference — referensi yang menahan objek di memori, meningkatkan retain count sebesar 1.
  • ARC secara otomatis menyisipkan operasi release dan retain, menghilangkan manajemen memori manual di Swift dan Objective-C.
  • Retain cycle terjadi ketika dua objek saling merujuk melalui referensi kuat — memori tidak pernah dibebaskan.
  • Weak Reference tidak meningkatkan penghitung referensi dan otomatis menjadi nil saat objek dibebaskan.
  • Unowned Reference tidak meningkatkan penghitung, tetapi mengasumsikan bahwa objek tidak hidup lebih lama dari pemiliknya.

Apa itu Strong Reference?

Strong Reference — adalah jenis referensi ke objek yang mencegah penghancurannya oleh pengumpul sampah atau sistem manajemen memori. Selama setidaknya ada satu referensi kuat ke objek, memori di bawahnya tidak dibebaskan. Ini adalah mekanisme dasar yang menjadi dasar ARC di Swift dan Objective-C serta pengumpulan sampah di Java dan Kotlin.

Konsep referensi kuat sangat fundamental untuk semua bahasa dengan manajemen memori otomatis. Dalam sistem dengan ARC, setiap referensi kuat meningkatkan penghitung referensi objek. Ketika penghitung turun ke nol, objek segera dialokasikan. Di Java dan Kotlin dengan pengumpul sampah, referensi kuat memastikan bahwa objek dapat dijangkau dan tidak akan dikumpulkan oleh GC.

Menurut data WWDC 2021, sekitar 35% kebocoran memori di aplikasi iOS terkait dengan penggunaan referensi kuat yang tidak tepat dan siklus retensi. Dalam pengembangan Android, kebocoran melalui strong reference implisit di penutupan dan panggilan balik adalah penyebab paling umum kedua masalah memori setelah Context Leak.

Untuk bekerja secara efisien dengan memori, perlu memahami perbedaan antara referensi strong, weak dan unowned serta memilih jenis referensi yang tepat tergantung pada kepemilikan dan masa hidup objek.

Bagaimana ARC mengubah pendekatan manajemen memori

Sebelum diperkenalkannya ARC, pengembang secara manual memanggil retain dan release untuk setiap objek, yang menyebabkan banyak kesalahan. ARC, diperkenalkan oleh Apple pada tahun 2011 dengan rilis LLVM 3.0, mengotomatiskan proses ini dengan menganalisis grafik kepemilikan pada tahap kompilasi. Kompiler sendiri menyisipkan panggilan retain, release dan autorelease di tempat yang tepat.

Menurut Clang Static Analyzer, pengenalan ARC mengurangi jumlah bug terkait memori di aplikasi iOS sebesar 70%. Bagi pengembang, ini berarti manajemen memori menjadi lebih aman, tetapi pada saat yang sama muncul kebutuhan untuk memahami bagaimana referensi kuat bekerja di balik layar — untuk menghindari retain cycles.

Di Kotlin dan Java, peran ARC dilakukan oleh pengumpul sampah, tetapi prinsip referensi kuat tetap sama: GC Roots — ini adalah titik masuk di mana objek dipertahankan oleh referensi kuat. Selama objek dapat dijangkau melalui rantai referensi kuat dari GC Root, objek tersebut tidak akan dikumpulkan.

Bagaimana Strong Reference bekerja di ARC?

ARC (Automatic Reference Counting) bekerja berdasarkan prinsip penghitungan referensi untuk setiap objek di heap. Ketika referensi kuat baru ke objek dibuat, penghitung meningkat (retain). Ketika referensi dihancurkan atau ditimpa, penghitung menurun (release). Ketika penghitung mencapai nol, objek segera dihapus dari memori.

Mari kita lihat contoh di Swift. Saat membuat instance kelas, ARC mengalokasikan memori dan menetapkan retain count ke 1. Setiap penugasan baru ke variabel lain meningkatkan penghitung. Ketika variabel keluar dari ruang lingkup, penghitung menurun:

swift
class ProfileViewController {
    var nameLabel: String?
    var avatarImage: UIImage?

    func loadProfile() {
        // retain count = 1 untuk instance baru
        let user = User(name: "Ivan")
        // retain count = 2 setelah penugasan nameLabel
        nameLabel = user.name
        // keluar dari metode — user keluar dari scope, retain count = 1
    }
}

Dalam kode ini, ARC memastikan bahwa objek User tetap di memori selama setidaknya ada satu referensi kuat ke sana. Ketika fungsi loadProfile selesai, variabel lokal user dihancurkan, tetapi nameLabel masih menahan objek. Memori akan dibebaskan hanya ketika nameLabel tidak lagi ada atau ditimpa.

Di Kotlin, perilaku serupa disediakan melalui GC Roots. Selama ada rantai strong references yang dapat dilacak dari akar pengumpul sampah (misalnya, bidang statis atau thread aktif), objek tetap di memori. Perbedaannya adalah bahwa GC tidak membebaskan memori secara instan — ini terjadi secara asinkron setelah analisis keterjangkauan.

Kapan pelepasan memori terjadi

Di ARC, pelepasan terjadi secara sinkron pada saat penghitung dinolkan. Di Swift dan Objective-C, Anda tahu persis kapan objek akan dihapus. Di Kotlin dan Java, momen pelepasan tidak dapat diprediksi, tetapi ini dikompensasi oleh skema deteksi dependensi siklik yang lebih fleksibel di tingkat pengumpul sampah.

Retain Cycles dan kebocoran memori

Retain cycle (siklus retensi) — situasi di mana dua atau lebih objek memiliki referensi kuat timbal balik satu sama lain. Akibatnya, retain count mereka tidak pernah turun ke nol, dan memori tidak dibebaskan bahkan setelah objek tidak lagi dibutuhkan oleh aplikasi.

Contoh klasik: view controller induk menahan objek anak dengan referensi kuat, dan ia pada gilirannya menahan induk dengan referensi kuat. Ini tipikal untuk situasi dengan delegasi, penutupan, dan ekspresi lambda bersarang. Menurut Instruments Leaks, retain cycles merupakan hingga 60% dari semua kebocoran memori di aplikasi yang menggunakan ARC.

swift
class ParentViewController: UIViewController {
    var child: ChildViewController?

    func setupChild() {
        child = ChildViewController()
        // retain cycle: parent menahan child, child menahan parent melalui closure
        child?.onEvent = {
            self.handleEvent()
        }
    }

    func handleEvent() {}
}

Masalahnya di sini adalah bahwa penutupan onEvent menangkap self (ParentViewController) dengan referensi kuat, dan ParentViewController sendiri menahan child dengan referensi kuat. Kedua objek tidak akan pernah dibebaskan. Solusinya — gunakan weak self di penutupan untuk memutus siklus.

Di Kotlin, siklus serupa muncul saat menggunakan lambda yang menangkap objek eksternal. Pengumpul sampah JVM dapat mendeteksi siklus semacam itu seiring waktu, tetapi hanya jika objek tidak dapat dijangkau dari GC Roots. Jika siklus terkait dengan thread aktif atau konteks UI, kebocoran tetap ada sepanjang masa hidup aplikasi.

Strong vs Weak vs Unowned Reference

Memahami perbedaan antara jenis referensi — kunci manajemen memori yang aman. Strong Reference meningkatkan retain count. Weak Reference tidak meningkatkan retain count dan secara otomatis menjadi nil saat objek dibebaskan. Unowned Reference juga tidak meningkatkan retain count, tetapi tidak dinolkan — merujuknya setelah pembebasan menyebabkan crash.

Jenis referensiRetain countKeamananKapan digunakan
Strong+1Aman (default)Kepemilikan objek, relasi parent → child
WeakTidak berubahPeniadaan otomatis (safe)Delegasi, callback, referensi balik
UnownedTidak berubahRisiko crash saat referensi tertundaKetika objek dipastikan hidup lebih lama dari pemilik

Pemilihan jenis referensi ditentukan oleh hubungan kepemilikan. Jika objek B adalah bagian dari A dan tidak dapat ada tanpanya — gunakan Strong. Jika B dapat ada secara independen dan merujuk ke A untuk pemberitahuan — gunakan Weak. Unowned jarang diterapkan — hanya ketika masa hidup objek anak secara ketat tidak melebihi masa hidup induk.

Aturan praktis pemilihan

Apple Developer Documentation merekomendasikan: secara default gunakan strong untuk semua hubungan kepemilikan. Jika perlu menghindari retain cycle — tentukan referensi mana yang harus lemah. Biasanya ini adalah referensi balik dalam hierarki (child → parent). Di Kotlin, peran serupa dimiliki oleh WeakReference dari java.lang.ref, yang diterapkan untuk cache dan pola observer.

Cara memperbaiki masalah referensi kuat

Mendeteksi retain cycles — langkah pertama. Kedua — menghilangkannya dengan benar. Alat utama untuk memerangi siklus referensi kuat adalah mengganti salah satu referensi dengan weak atau unowned. Dalam bahasa dengan pengumpulan sampah, tambahan diterapkan WeakReference dengan pemeriksaan null manual sebelum setiap akses.

Di Swift dan Objective-C, perbaikan paling umum adalah menambahkan [weak self] di penutupan. Ini memastikan bahwa penutupan tidak menahan objek setelah dibebaskan. Di Kotlin, untuk tujuan serupa digunakan wrapper WeakReference atau pembersihan eksplisit referensi di onDestroy.

swift
class NetworkService {
    func fetchData(completion: @escaping (Data?) -> Void) {
        // penangkapan melalui weak self — retain cycle dikecualikan
        URLSession.shared.dataTask(
            with: URL(string: "https://api.example.com")!
        ) { [weak self] data, response, error in
            guard let self else { return }
            completion(data)
        }.resume()
    }
}

Dalam contoh ini, [weak self] memastikan bahwa NetworkService tidak akan ditahan oleh penutupan setelah tidak lagi diperlukan. Jika self telah dibebaskan sebelum permintaan selesai — guard let self else { return } keluar dari penutupan tanpa memanggil completion.

Untuk diagnosa retain cycles, gunakan Instruments Leaks untuk iOS atau Android Profiler + LeakCanary untuk Android. Alat-alat ini menunjukkan grafik retensi yang tepat dan menunjukkan referensi kuat mana yang mencegah pembebasan objek. Profiling memori secara teratur harus menjadi bagian dari pipeline CI/CD setiap proyek mobile.

Strong Reference di Swift dan Kotlin — perbandingan

Swift dan Kotlin menggunakan mekanisme manajemen memori yang fundamentally berbeda, tetapi konsep referensi kuat ada di keduanya. Di Swift, ARC diterapkan dengan pelepasan sinkron saat retain count = 0. Di Kotlin, digunakan GC pelacak yang secara asinkron membersihkan objek yang tidak dapat dijangkau.

ParameterSwift (ARC)Kotlin (JVM GC)
MekanismePenghitungan referensi (retain count)Pelacakan keterjangkauan (GC Roots)
PelepasanSinkron (saat penghitung dinolkan)Asinkron (melalui siklus GC)
Retain cycleTidak terdeteksi secara otomatisGC dapat mendeteksi, tetapi tidak segera
Weak refweak (peniadaan otomatis)WeakReference (pemeriksaan manual)

Perbedaan praktis utama: di Swift, retain cycle — adalah kebocoran yang terjamin. Di Kotlin, GC dapat memutus siklus jika objek tidak dapat dijangkau dari akar, tetapi masa hidup objek yang bocor tetap tidak dapat diprediksi. Oleh karena itu, di kedua bahasa, strategi terbaik adalah menghindari siklus referensi kuat pada tahap desain.

Untuk Swift, gunakan weak di pola delegasi dan penutupan. Untuk Kotlin — WeakReference atau komponen Lifecycle-aware yang secara otomatis membersihkan referensi saat pemilik dihancurkan. Dalam kedua pendekatan, tujuannya sama — mengecualikan referensi kuat di tempat yang menciptakan rantai retensi yang tidak dapat diputus.

Pertanyaan yang sering diajukan

Apa perbedaan Strong Reference dengan Weak Reference?

Strong Reference meningkatkan retain count objek dan mencegah pelepasannya selama referensi ada. Weak Reference tidak mengubah retain count dan secara otomatis menjadi nil ketika objek dihapus dari memori. Referensi kuat digunakan untuk kepemilikan, referensi lemah — untuk hubungan balik dan delegasi.

Apa itu retain cycle dan mengapa berbahaya?

Retain cycle — saling mengunci di mana dua objek saling menahan dengan referensi kuat. Retain count mereka tidak pernah turun ke nol, memori tidak dibebaskan. Ini menyebabkan kebocoran memori: objek tetap di heap selamanya, aplikasi mengonsumsi semakin banyak sumber daya dan akhirnya crash dengan OutOfMemory.

Bagaimana cara mendeteksi retain cycle di aplikasi iOS?

Gunakan Instruments Leaks dari Xcode — mulai profiling dengan template Leaks, jalankan skenario di aplikasi dan periksa indikator kebocoran. Untuk diagnosis yang akurat, beralihlah ke tab Cycles & Roots — ini akan menunjukkan grafik strong reference timbal balik yang membentuk siklus yang tidak dapat diputus.

Kapan harus menggunakan Unowned daripada Weak?

Unowned terapkan ketika masa hidup objek anak pasti tidak melebihi masa hidup induk — misalnya, saat mengikat objek ke ruang lingkup yang ditentukan secara ketat. Jika ragu, gunakan Weak, karena merujuk ke unowned yang telah dibebaskan menyebabkan crash aplikasi.

Apakah referensi kuat mempengaruhi kinerja aplikasi?

Secara tidak langsung — ya. Setiap retain dan release di ARC adalah operasi atomik dengan overhead. Dengan jumlah objek yang besar dalam siklus, ini dapat mempengaruhi kinerja. Namun masalah utamanya bukanlah kecepatan ARC, melainkan kebocoran memori karena jenis referensi yang salah dipilih.

Kesimpulan

  • Strong Reference — mekanisme dasar kepemilikan objek, menahannya di memori melalui peningkatan retain count.
  • ARC mengotomatiskan manajemen memori di Swift dan Objective-C, menghilangkan retain dan release manual, tetapi tidak melindungi dari retain cycles.
  • Retain cycle terjadi pada referensi kuat timbal balik — ini adalah penyebab utama kebocoran memori di sistem ARC.
  • Referensi Weak dan Unowned memutus siklus referensi kuat tanpa meningkatkan retain count.
  • Pemilihan jenis referensi ditentukan oleh hubungan kepemilikan: Strong untuk parent→child, Weak atau Unowned untuk child→parent.
  • Instruments Leaks dan LeakCanary — alat utama untuk mendeteksi referensi kuat bermasalah di iOS dan Android.
  • Rancang grafik kepemilikan di awal — ini lebih murah daripada memperbaiki kebocoran memori setelah rilis aplikasi.

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