Nim menyediakan beberapa model manajemen memori yang dipilih saat kompilasi melalui sakelar --mm, tanpa mengubah satu baris kode pun. Topik ini membahas nilai-nilai yang sah untuk sakelar tersebut, mengenalkan kolektor warisan refc yang masih dapat dipilih sampai sekarang, dan merangkum kapan setiap pilihan paling tepat dipakai. Semua contoh dijalankan dengan Nim 2.4.0, sehingga daftar opsinya dapat diverifikasi langsung dari kompilator yang sama dengan yang dipakai pembaca.
Sakelar –mm pada kompilator#
Sakelar --mm menentukan model manajemen memori yang disertakan kompilator ke dalam program. Daftar lengkap nilainya terbaca langsung dari teks bantuan kompilator, dan baris keduanya menyebut nilai bawaannya.
# tampilkan opsi pemilihan model memori pada kompilator
nim --fullhelp 2>&1 | grep -A1 -- "^ --mm:" --mm:orc|arc|refc|markAndSweep|boehm|go|none|regions
select which memory management to use; default is 'orc'Tabel berikut merangkum kedelapan nilai tersebut beserta kegunaannya.
| Nilai | Model | Catatan singkat |
|---|---|---|
orc | penghitungan referensi ditambah pengumpul siklus | bawaan sejak Nim 2.0 |
arc | penghitungan referensi tanpa pengumpul siklus | kode mesin lebih kecil, siklus tidak dikumpulkan |
refc | kolektor warisan berbasis penghitungan tertunda | pilihan kompatibilitas untuk kode lama |
markAndSweep | mark-and-sweep sederhana | heap lokal per thread |
boehm | kolektor Boehm | heap bersama, kompatibel valgrind |
go | kolektor milik Go untuk interop Go | jarang dipakai |
none | tanpa pengelola memori | memori tidak pernah dibebaskan otomatis |
regions | manajemen berbasis region | mode khusus untuk kebutuhan tertentu |
Dari kedelapan nilai itu, dua yang pertama adalah model modern berbasis hook yang dibahas pada topik ARC dan ORC. Sisanya adalah kolektor penuh atau mode khusus, dan satu di antaranya, yaitu refc, masih layak dikenali karena jejaknya panjang di ekosistem Nim.
Sakelar ini bekerja pada tingkat kompilator, bukan pada tingkat pustaka yang diimpor oleh kode. Pilihannya menentukan bagian runtime mana yang ditautkan ke dalam biner, sehingga seluruh program memakai satu model yang sama dan tidak ada campuran model antar modul. Karena itu pula pengubahan nilai --mm memicu kompilasi ulang yang menyeluruh, dan biner yang dihasilkan dari nilai berbeda tidak dapat disatukan dalam satu program. Satu nilai berlaku untuk satu kali kompilasi penuh.
Kolektor warisan refc#
refc adalah kolektor yang mengelola memori Nim sejak generasi awal, jauh sebelum ARC diperkenalkan. Namanya berasal dari deferred reference counting, yaitu penghitungan referensi yang pembaruannya ditunda agar operasi penugasan menjadi murah, dan dilengkapi kolektor cadangan mark-and-sweep untuk mengumpulkan siklus. Dokumentasi memori Nim menambahkan bahwa refc memakai heap lokal per thread dan berjalan secara inkremental, sehingga bukan kolektor stop-the-world. Seluruh mekanisme itu berbeda dari ARC yang memusnahkan objek tepat saat penghitungnya nol.
Sifat tertunda itu terasa pada cara refc menangani penugasan. Pembaruan penghitung untuk rujukan yang keluar dari fungsi ditumpuk dan diproses kemudian, sehingga biaya per penugasan rendah tetapi waktu pembebasan memori menjadi sulit diprediksi. Kolektor cadangan mark-and-sweep menyusul pekerjaan itu dengan menandai objek yang masih terjangkau dari akar, lalu menyapu sisanya, termasuk siklus yang tidak dapat diselesaikan oleh penghitungan referensi. Perpaduan dua mekanisme inilah yang menjadikan refc kolektor penuh, berbeda dari ARC yang murni berbasis penghitung.
Program berikut dipilih karena hanya bergantung pada wadah bawaan, sehingga dapat dikompilasi dengan kolektor mana pun. Kompilasi ulang programnya dengan --mm:refc dan bandingkan hasilnya dengan kompilasi bawaan.
type
Buffer = object
kapasitas: int
data: seq[int]
proc isi(b: var Buffer, nilai: int) =
for i in 1 .. b.kapasitas:
b.data.add(nilai * i)
var b = Buffer(kapasitas: 5)
b.isi(3)
echo "isi buffer: ", b.data
echo "jumlah elemen: ", b.data.len# kompilasi program buffer dengan kolektor warisan refc
nim c --mm:refc --hints:off buffer.nim
# jalankan program hasil kompilasi
./bufferisi buffer: @[3, 6, 9, 12, 15]
jumlah elemen: 5Program yang sama berjalan tanpa penyesuaian, dan itulah tujuan utama refc hari ini, yaitu menjaga kode lama tetap dapat dikompilasi serta menjadi pembanding ketika performa diukur antar kolektor. Perlu dicatat bahwa perilaku runtime refc tidak identik dengan ARC dan ORC, misalnya pada waktu objek benar-benar dibebaskan. Program yang bergantung pada hook seperti =destroy sebaiknya diuji ulang sebelum dipindah ke refc atau sebaliknya.
Memilih pengelola yang tepat#
Pilihan bawaan, --mm:orc, adalah titik mulai yang tepat untuk program Nim modern karena memadukan pemusnahan deterministik dengan pengumpulan siklus. Pindah ke --mm:arc hanya dengan alasan yang terukur, misalnya program embedded yang mengutamakan ukuran kode mesin dan tidak membentuk siklus referensi, atau sistem waktu nyata (realtime) yang menuntut performa tanpa jeda kolektor. refc dipilih untuk kode warisan yang belum diuji pada model baru atau untuk membandingkan profil memori antar kolektor. Sementara itu, markAndSweep, boehm, dan go dipakai pada skenario khusus seperti kebutuhan interop tertentu, dan none hanya untuk kasus yang mengelola memori sepenuhnya secara manual.
Dokumentasi juga memberi catatan batas yang berguna. Kompilasi ke backend JavaScript menyerahkan manajemen memori sepenuhnya kepada GC milik JavaScript, sehingga sakelar --mm tidak berperan di sana. Untuk program di server atau alat baris perintah, kombinasi --mm:orc dengan profil memori berkala sudah mencakup mayoritas kebutuhan, dan perpindahan antar model cukup dilakukan dengan mengganti satu sakelar saja.
Sebelum berpindah kolektor, ukur dulu alasannya. Perbandingan yang jujur memerlukan beban kerja yang sama, opsi kompilasi yang sama selain --mm, dan metrik yang jelas seperti waktu eksekusi, konsumsi memori puncak, atau ukuran biner. Hasil pengukuran itu juga mudah basi karena kolektor terus diperbarui, sehingga keputusan perpindahan sebaiknya ditinjau ulang setiap kali versi Nim yang dipakai berganti. Tanpa angka seperti ini, sakelar --mm hanya menjadi sumber perbedaan yang tidak terjelaskan antara dua build.
Ringkasan#
- Sakelar
--mmmemilih model manajemen memori saat kompilasi, denganorcsebagai bawaan sejak Nim 2.0. - refc adalah kolektor warisan berbasis penghitungan tertunda dengan cadangan mark-and-sweep untuk siklus, dan masih dapat dipilih lewat
--mm:refc. - Program yang hanya memakai wadah bawaan berjalan sama di semua kolektor, tetapi waktu pembebasan memorinya berbeda.
- Pilihan pengelola bergantung pada target program, mulai dari ORC untuk kasus umum, ARC untuk ukuran kode, hingga refc untuk kompatibilitas.
Referensi#
- Nim Compiler User Guide — Nim documentation
— Dokumentasi resmi sakelar
--mmbeserta daftar nilai yang sah. - Nim’s Memory Management — Nim documentation — Karakteristik setiap kolektor, termasuk refc, markAndSweep, boehm, dan go.