Pengelolaan Memori

Pertanyaan pertama yang dimiliki sebagian besar developer Java adalah bagaimana pengelolaan memori diimplementasikan oleh J2ObjC, karena Java memiliki pembersihan sampah memori dan Objective-C tidak secara default. Apa yang dimiliki iOS adalah dua metode pengelolaan memori: penghitungan referensi dan Automatic Reference Counting (ARC).

J2ObjC menghasilkan kode pengelolaan memori yang berbeda, bergantung pada metode yang dipilih. Terjemahkan dengan opsi -use-arc untuk membuat kode yang menggunakan ARC. Secara default, metode ini menggunakan penghitungan referensi manual.

Jumlah Referensi

Metode penghitungan referensi membuat kepemilikan objek bersifat eksplisit. Metode memiliki objek saat membuatnya, hingga melepaskan objek tersebut. Saat menerima objek dari metode lain, metode penerimaan akan mempertahankan objek jika perlu direferensikan setelah metode ditampilkan. Jika metode tidak lagi perlu mereferensikan objek, metode tersebut harus melepaskannya. Jika jumlah retensi objek adalah nol, memorinya akan dikosongkan dan objek tidak lagi valid. Saat objek dibebaskan, metode dealloc() dipanggil untuk melepaskan kepemilikan variabel instance.

Salah satu masalah dari teknik ini adalah bagaimana mentransfer kepemilikan suatu objek. Misalnya, metode factory dapat dipanggil untuk membuat objek. Jika metode factory melepaskan objek sebelum mengembalikannya (karena tidak ingin lagi memiliki objek), objek tersebut akan dibebaskan sebelum metode panggilan dapat mempertahankannya.

Untuk mentransfer kepemilikan objek, suatu metode mengiriminya pesan rilis otomatis (bukan pesan rilis), yang menunda pesan rilis. Hal ini memungkinkan metode factory membuat objek yang akan ditampilkan, dan melepaskan kepemilikannya tanpa membatalkan validasi objek. Pada interval yang teratur (seperti setelah setiap iterasi loop peristiwa dalam aplikasi iOS), kumpulan autorelease akan "dihabiskan", yang berarti semua objek dalam kumpulan tersebut akan dikirimi pesan rilis yang ditangguhkan. Setiap objek yang mempertahankan jumlah turun ke nol akan dibebaskan seperti biasa.

Karena beban pada pengelolaan memori dibebankan pada developer, kebocoran memori mudah dilakukan dengan metode penghitungan referensi. Namun, Apple merekomendasikan beberapa praktik terbaik untuk meminimalkan masalah ini, yang diterapkan J2ObjC.

Ada juga dukungan alat dan runtime untuk mendeteksi kebocoran memori. Runtime Objective-C melaporkan setiap kebocoran yang terdeteksi saat aplikasi keluar, yang merupakan salah satu alasan mengapa J2ObjC menerjemahkan pengujian JUnit menjadi biner yang dapat dieksekusi. Xcode menggunakan CLI, dan compiler tersebut memiliki analisis statis yang sangat baik untuk masalah memori, yang disediakan Xcode dengan perintah Analyze-nya.

Penghitungan Referensi Otomatis (ARC)

ARC adalah metode pengelolaan memori yang direkomendasikan Apple. Library ini memindahkan tanggung jawab atas penghitungan referensi ke compiler, yang menambahkan metode penahanan, rilis dan rilis otomatis yang sesuai selama kompilasi. ARC mendukung referensi lemah untuk perangkat yang menjalankan iOS 5 dan yang lebih baru.

Sebaiknya project menggunakan ARC untuk kode yang diterjemahkan. Kode Objective-C yang ditranspilasi sama seperti kode Objective-C yang ditulis tangan. Menggunakan ARC dapat membantu developer menghindari error umum terkait memori seperti pelepasan berlebihan atau kurang referensi, sehingga pengelolaan memori menjadi lebih sederhana dan tidak terlalu rentan terhadap error.

Perhatikan bahwa secara default, ARC tidak aman untuk pengecualian. Secara khusus, ini membocorkan memori saat pengecualian dilempar. Karena pengecualian lebih umum terjadi di Java dan biasanya dapat dipulihkan, hal ini dapat menjadi masalah. Menggunakan -fobjc-arc-exceptions saat mengompilasi dengan lengkungan akan memperbaiki kebocoran dengan biaya performa yang dapat diterima.

Sebaiknya project baru juga menggunakan ARC untuk kode Objective-C yang ditulis tangan, dan hanya melakukan fallback ke penghitungan referensi manual jika data pembuatan profil menunjukkan masalah performa yang nyata. Baik kode ARC maupun non-ARC dapat dikompilasi dan ditautkan ke aplikasi yang sama tanpa masalah.

Referensi Lemah

Kolom dapat dianotasi dengan com.google.devtools.j2objc.Weak, yang digunakan transpiler untuk membuat kolom yang mengikuti semantik referensi yang lemah Objective-C. Saat menggunakan penghitungan referensi, hal ini berarti kolom tidak dipertahankan saat diinisialisasi, dan akan dirilis otomatis saat instance yang memuatnya dirilis. Dengan ARC, kolom lemah ditandai dengan anotasi __unsafe_unretained, dan properti terkait dideklarasikan sebagai lemah.

Pada beberapa kasus, instance class dalam masuk ke siklus referensi dengan instance luarnya. Di sini, anotasi com.google.devtools.j2objc.WeakOuter digunakan untuk menandai class dalam, sehingga referensi ke class luar diperlakukan seperti dijelaskan di atas. Kolom lain di class dalam tidak terpengaruh oleh anotasi ini.

J2ObjC juga mendukung class WeakReference, sehingga kode Java yang menggunakannya akan bekerja dengan cara yang sama saat diterjemahkan. Perlu diketahui bahwa WeakReference pada dasarnya bersifat nondeterministik pada JVM; aplikasi yang ingin menghindari kebocoran memori sambil mempertahankan prediktabilitas sebaiknya memilih @Weak dan @WeakOuter.

Alat Pengelolaan Memori