9 poin oleh GN⁺ 2025-06-14 | 2 komentar | Bagikan ke WhatsApp
  • Ditulis langsung oleh Jason Evans, tokoh utama di balik pengembangan jemalloc, ini adalah catatan reflektif yang meninjau perjalanan pengembangan jemalloc selama sekitar 20 tahun dalam 5 fase, sambil merekam dengan jujur keberhasilan dan kegagalan, keterbatasan proyek open source, serta proses kemunduran akibat perubahan di dalam perusahaan
  • Allocator memori jemalloc dimulai pada 2004 dan digunakan secara luas selama sekitar 20 tahun, tetapi baru-baru ini pengembangan resminya dihentikan karena perubahan internal di Meta
  • Melalui berbagai fase seperti integrasi awal ke FreeBSD, penyelesaian masalah performa Firefox, dan adopsi skala besar di Facebook, jemalloc mengumpulkan banyak pengalaman optimisasi performa dan porting
  • Sambil melewati beragam tantangan seperti masalah fragmentasi ruang penyimpanan dan skalabilitas, berbagai fitur ditambahkan seperti peningkatan performa, pengumpulan statistik, dan infrastruktur pengujian
  • Seiring perubahan budaya perusahaan di Meta, penurunan investasi teknis dan ketiadaan personel pemelihara inti menyebabkan pengembangan jangka panjang berhenti
  • Penghapusan Valgrind dan ketiadaan umpan balik dari pengguna eksternal menjadi batasan struktural yang memperlemah keterhubungan dengan ekosistem open source
  • Ke depan, kemungkinan perkembangan baru melalui fork tetap terbuka, tetapi pengembangan utama resmi tampaknya tidak akan berlanjut lagi

Ikhtisar jemalloc

  • jemalloc adalah allocator memori open source yang pertama kali dirancang pada 2004, dikembangkan untuk meningkatkan performa dan skalabilitas, lalu selama 20 tahun digunakan secara aktif di berbagai proyek open source utama dan infrastruktur big tech
  • Karena pengembangan utamanya baru-baru ini dihentikan, ke depannya yang diharapkan adalah pemeliharaan melalui fork atau oleh masing-masing organisasi

Fase 0: Lyken

  • Pada 2004, pengembangan dimulai dari allocator memori manual dalam proses pembuatan bahasa pemrograman untuk komputasi ilmiah bernama Lyken
  • Allocator internal Lyken secara fungsional selesai pada Mei 2005
  • Setelah allocator tersebut diintegrasikan ke FreeBSD, di Lyken ia dihapus dan hanya menyisakan wrapper tipis untuk allocator sistem
  • Alasannya, setelah integrasi ke FreeBSD, kekurangan allocator sistem menjadi lebih jelas, khususnya pada pelacakan alokasi per thread
  • Menariknya, kemudian fitur pengumpulan statistik yang dulu dibutuhkan pada masa Lyken akhirnya ditambahkan ke jemalloc

Fase 1: FreeBSD

  • Pada 2005, ketika komputer multiprosesor mulai menjadi umum, FreeBSD masih memakai phkmalloc, tetapi allocator itu tidak cocok untuk lingkungan thread paralel
  • Karena allocator Lyken menunjukkan keunggulan yang jelas dalam skalabilitas, allocator itu diintegrasikan ke FreeBSD dan segera diberi nama jemalloc
  • Namun, pada aplikasi seperti KDE muncul masalah fragmentasi yang serius, sehingga kelangsungan hidupnya sempat diragukan
  • Penyebab fragmentasi adalah metode alokasi ruang gabungan tanpa pemisahan ukuran, dan setelah penelitian mendalam, strukturnya diubah besar-besaran menjadi algoritme pemisahan area berdasarkan ukuran
  • Isi proses ini didokumentasikan dalam makalah BSDCan 2006

Fase 1.5: Firefox

  • Menjelang rilis Mozilla Firefox 3 pada 2007, fragmentasi memori di lingkungan Windows menjadi isu besar
  • Porting jemalloc ke Linux mudah dilakukan, tetapi Windows jauh lebih rumit
  • jemalloc yang tersimpan di FreeBSD libc kemudian di-fork oleh Mozilla untuk meningkatkan portabilitas dan kompatibilitas
  • Seiring waktu Mozilla menyumbangkan banyak perbaikan ke upstream jemalloc, tetapi versi fork selalu menunjukkan performa yang lebih tinggi
  • Tidak jelas apakah itu disebabkan regresi performa atau optimisasi yang disesuaikan untuk lingkungan tertentu

Fase 2: Facebook

  • Saat bergabung dengan Facebook pada 2009, hambatan terbesar jemalloc adalah kurangnya alat seperti profiling dan deteksi kebocoran memori
  • Untuk melengkapinya, fitur heap profiling kompatibel dengan pprof diperkenalkan pada jemalloc 1.0.0
  • Setelah pengembangan dipindahkan ke Github, bersama pengguna dan kontributor eksternal dilakukan banyak perbaikan seperti infrastruktur pengujian, dukungan Valgrind, statistik JSON, dan manajemen halaman baru
  • Secara internal, sistem telemetri raksasa milik Facebook sangat membantu optimisasi performa dan pencegahan regresi
  • 3.x: pengenalan infrastruktur pengujian dan dukungan Valgrind
  • 4.x: penambahan decay-based purging dan statistik JSON
  • 5.x: perubahan dari desain berbasis chunk ke extent, sekaligus meletakkan dasar untuk pemanfaatan huge page 2MiB
  • Analisis performa berbasis telemetry di internal Facebook memainkan peran penentu dalam optimisasi
  • Pada versi 5.0.0, dukungan Valgrind dihapus karena tidak digunakan secara internal, tetapi keputusan ini memicu penolakan kuat dari pihak eksternal seperti pengembang Rust
  • Setelah itu, perubahan organisasi di Facebook/Meta mengecilkan tim jemalloc, dan strategi bisnis bergeser dari investasi teknis inti ke efisiensi
  • Akibatnya, pengembangan fitur besar seperti Huge Page Allocation mandek, dan sebagian pekerjaan tidak pernah diselesaikan
  • Setelah Evans keluar pada 2017, pengembangan dipertahankan selama beberapa tahun di bawah pimpinan Qi Wang
  • Bahkan setelah alih kepemimpinan tim, beberapa kontributor tetap menjaga proyek ini, tetapi tidak ada lagi pengelola visi jangka panjang

Fase 4: Stasis

  • Saat ini pengembangan upstream jemalloc telah berakhir, dan Meta juga menempuh arah tersendiri sesuai kebutuhan internalnya
  • Utang teknis pada codebase yang ada sudah besar, sehingga refactoring besar-besaran perlu didahulukan
  • Kebutuhan Facebook/Meta dan kebutuhan pengguna eksternal tidak lagi selaras
  • Jika pengembangan ingin dilanjutkan lagi di masa depan, pembersihan utang teknis selama ratusan jam harus didahulukan, dan penulis sendiri tidak lagi memiliki motivasi untuk itu
  • Berdasarkan branch dev atau 5.3.0, fork eksternal tetap dimungkinkan, sehingga selalu ada kemungkinan lahirnya proyek baru berbasis fork

Refleksi dan pelajaran

  • Konflik akibat penghapusan dukungan Valgrind berasal dari kurangnya pemahaman atas penggunaan eksternal
  • Fakta bahwa jemalloc digunakan di Android pun baru diketahui dua tahun kemudian
  • Proyek ini memang sepenuhnya terbuka di GitHub, tetapi kontributor inti dari organisasi luar tidak bisa bertahan secara berkelanjutan
    • Upaya Mike Hommey dari Firefox maupun percobaan migrasi ke CMake semuanya berakhir tidak tuntas
  • Dari pengalaman ini, sekadar membuka kode tidak otomatis menjadikannya proyek independen yang berkelanjutan
  • Ditekankan bahwa open source tidak bisa bertahan hanya dengan dipublikasikan; pembinaan kontributor inti dan tata kelola sangat penting

Pernyataan penutup

  • jemalloc adalah pengalaman yang istimewa bahkan bagi penulis, yang selama lebih dari 25 tahun merupakan pendukung garbage collection
  • Kini ia kembali fokus pada pengembangan sistem garbage collection, sambil menyampaikan rasa terima kasih yang mendalam kepada semua orang yang telah membantu jemalloc

2 komentar

 
ganadist 2025-06-14

Ada juga versi terjemahan lengkapnya.
https://rosettalens.com/s/ko/jemalloc-postmortem

 
GN⁺ 2025-06-14
Komentar Hacker News
  • Saya memahami keputusan untuk mengarsipkan repositori upstream. Sebelum saya meninggalkan Meta, tim jemalloc kami memang tidak punya kapasitas untuk menanggapi segala macam issue yang masuk di GitHub (misalnya pernah ada seseorang membuka issue karena pengujian gagal di lingkungan Itanium, dan itu terasa agak lucu bagi saya). Meski begitu, melihat situasi seperti ini tetap terasa disayangkan. Sampai sekarang pun saya masih merasa jemalloc adalah pilihan implementasi malloc serbaguna yang performanya paling baik sekaligus paling mudah digunakan. TCMalloc juga sangat bagus, tetapi kalau tidak memakai bazel, menurut saya penggunaannya benar-benar sulit (akhir-akhir ini bazel 7.4.0 menambahkan cc_static_library, jadi mengekspornya sebagai pustaka statis sedikit lebih mudah, tetapi poin itu tetap relevan). Saya berniat bertanya kepada Qi apakah sebelum repositorinya diarsipkan lagi, kita bisa membuat satu rilis 6.0 terakhir. Kalau memang rilis terakhir, rasanya bagus juga untuk sedikit memodernkan konfigurasi bawaan. Misalnya, peningkatan besar adalah menonaktifkan pengaturan cache oblivious dari default karena namanya membingungkan dan membuat size-class 16 KiB membengkak sia-sia menjadi 20 KiB. Bukan bermaksud menyalahkan pilihan sebelumnya (yakni keputusan awal Jason); ketika saya membahasnya dengan Qi dan David saat itu, rendahnya associativity TLB pada masa itu dibanding sekarang memang alasan yang masuk akal. Dalam konteks serupa, menaikkan page size bawaan dari 4 KiB ke nilai yang lebih besar (sekitar 16 KiB) juga akan menjadi perubahan yang baik. Ini akan menaikkan ambang large size-class (titik saat beberapa alokasi yang biasanya ditempatkan ke slab beralih menjadi dialokasikan ke rentang terpisah masing-masing) dari 16 KiB ke 64 KiB, jadi dampaknya besar. Sebelum saya meninggalkan Meta, saya sempat meninjau penerapan perubahan ini pada layanan internal utama; itu merupakan optimasi yang mengurangi penggunaan CPU beberapa persen, dengan konsekuensi sedikit kenaikan memori akibat fragmentasi RAM. Selain itu masih ada beberapa hal lain yang ingin saya ubah (misalnya mengubah default metadata_thp dari disabled menjadi auto, mengubah sizing extent untuk slab dari kelipatan tepat ukuran halaman menjadi pendekatan yang mengurangi fragmentasi dengan mengizinkan pemborosan sekitar 1%, dan sebagainya). Namun, pengaturan-pengaturan yang saya sebutkan tadi kemungkinan akan menjadi perubahan terbesar

    • Orang yang membuka issue kegagalan test suite Itanium itu adalah saya sendiri

    • Menurut saya, kisah pengalaman nyata dan insight orang dalam seperti inilah yang membuat saya terus kembali ke Hacker News. Saya penasaran kenapa TCMalloc sulit dipakai tanpa bazel (saya benar-benar bertanya karena ingin tahu)

    • Saya berharap pengetahuan internal penting seperti ini dipublikasikan dalam materi yang lebih panjang seperti dokumentasi resmi atau tulisan blog. Saat ini dokumentasi resminya terasa terlalu minim. Akan bagus jika banyak pengetahuan hasil pekerjaan di dalam Meta dibagikan sebelum terlupakan seiring waktu

    • Agak disayangkan bahwa perangkat lunak sebagus ini tidak dimanfaatkan semestinya karena proses build dan integrasinya rumit

    • Anda menyebut bahwa “tim jemalloc tidak punya cukup kapasitas untuk menangani issue acak yang muncul di GitHub”, dan saya penasaran. Apa latar belakangnya sehingga pengelolaan issue tidak berjalan lancar meskipun Meta tampaknya punya cukup orang untuk mengelola proyek tersebut? Kalau saya salah memahami situasinya, mohon dikoreksi

  • Saya ingin menyampaikan betapa besar dampak pekerjaan Jason bagi pekerjaan kami. Perusahaan kami cukup besar dan memproses ratusan juta gambar/video setiap hari. Pada beberapa tahun awal, kami sangat menderita karena masalah fragmentasi memori. Lalu suatu hari kami mengadopsi jemalloc, hanya mengubah dua baris di Dockerfile, dan semua masalah langsung terselesaikan. Sekarang kami adalah perusahaan dengan pendapatan puluhan miliar, dan semua layanan serta Dockerfile kami memakai jemalloc. Saya sungguh ingin menyampaikan rasa terima kasih yang mendalam

    • Secara praktis, banyak layanan pemrosesan gambar berbasis golang merekomendasikan atau menggunakan jemalloc. Berdasarkan 3 teratas di topik resize-images (per 2025-06-13), imaginary menggunakannya seperti ini di Dockerfile, imgproxy juga dibahas di repo imaginary dengan merujuk ke dokumentasi yang diarsipkan, dan imagor juga memakai jemalloc di lokasi ini

    • Saya bertanya karena benar-benar penasaran (sama sekali bukan sindiran): apakah Anda juga pernah berdonasi? Rasanya mengungkapkan terima kasih lewat uang adalah bentuk apresiasi terbaik, bukan?

  • Soal komentar bahwa “jemalloc dikeluarkan dari biner Rust lebih cepat daripada yang diharapkan”, saya ingin berbagi bahwa issue itu sebenarnya hanya salah satu dari beberapa penyebab. Latar belakang terkait bisa dilihat di komentar ini. Dan jemalloc sendiri baru benar-benar dihapus dua tahun penuh setelah issue itu pertama kali diangkat (lihat: PR ini)

    • Menarik bahwa di antara beberapa issue yang disebut di sana, masalah hardcoded page size pada arm64 ternyata sampai sekarang masih belum diselesaikan di upstream. Karena ini, pengembang aplikasi harus menyediakan beberapa biner Linux arm64 terpisah atau melepas dukungan untuk sebagian platform. Saya jadi penasaran apakah kalau dynamic page size diperkenalkan (dengan menerapkan patch biner dinamis ala ftrace demi performa), hasilnya akan jauh lebih lambat daripada sekarang
  • Selama bertahun-tahun, saya selalu punya kebiasaan memakai jemalloc di semua game engine yang saya buat. Di lingkungan win32, performanya jauh lebih cepat daripada allocator bawaan, dan ada keuntungan besar karena memakai allocator yang sama di semua platform. Saya pertama kali mengenalnya ketika jemalloc terintegrasi di FreeBSD, dan sejak itu saya terus menggunakannya. Saya bangga merasa bahwa berkat jemalloc, banyak pemain game bisa mendapatkan kesenangan

    • allocator bawaan windows memang benar-benar buruk. Jemalloc adalah yang terbaik
  • Tulisan yang bagus — saya penasaran apakah Facebook (sekarang Meta) sudah tidak lagi memakai jemalloc itu sendiri, atau hanya masuk fase maintenance. Saya juga bertanya-tanya apakah mereka mungkin beralih ke tcmalloc atau allocator lain. Ada kalimat bahwa “di Facebook Infrastructure Engineering, penekanannya bergeser dari investasi pada teknologi inti ke ROI”

    • Saat saya keluar dari Meta hampir 2 tahun lalu (dan saya rasa tidak banyak berubah sampai sekarang), jemalloc masih dipakai dengan static linking di semua biner di Meta. Untuk pertanyaan apakah bisa dengan mudah beralih ke tcmalloc atau allocator lain, jawabannya adalah tidak semudah itu karena jemalloc sudah terintegrasi sangat dalam ke ekosistem internal perusahaan. Mulai dari plumbing telemetri Strobelight, berbagai extension yang dipakai dengan menyesuaikan jemalloc (misalnya arena manual yang langsung memakai custom extent hook), sampai fakta bahwa sebagian besar aplikasi benar-benar berevolusi agar bisa memaksimalkan karakteristik jemalloc, semuanya saling terkait

    • Perubahan besar belakangan ini adalah semua maintainer utama jangka panjang jemalloc sudah pergi. Namun ironisnya, sekarang justru ada lebih banyak perhatian terhadap proyek ini di dalam Facebook dibanding sebelumnya, dan setelah beberapa issue kontroversial baru-baru ini, saya optimistis ke depan arahnya bisa lebih mempertimbangkan Qi, Jason, dan juga para pengguna eksternal

    • Meta masih aktif mengembangkan fork versinya sendiri di sini

  • Merupakan kehormatan bagi saya bisa ikut terlibat dalam pekerjaan yang berpengaruh ini selama bertahun-tahun, dari Firefox hingga Facebook

    • Pada momen yang tepat, saya juga ingin meninggalkan ucapan terima kasih di sini. Saya tidak menyangka tulisan ini akan muncul hari ini, tetapi merupakan kehormatan bisa ikut menjadi bagian kecil dari perjalanan besar ini. Saya juga ingin berterima kasih kepada @je, qi, david, serta para kontributor pada masa itu dan setelahnya

    • Saya rasa kepemimpinan Anda yang mendorong agar Facebook terus berinvestasi pada teknologi inti benar-benar membuahkan hasil semaksimal mungkin. Inovasi seperti GraphQL, PyTorch, dan React bisa terjadi karena fondasi seperti ini

  • Kutipan FTA bahwa “ketika orang dihadapkan pada pilihan-pilihan yang mustahil, mereka hanya bisa 1) mengambil keputusan buruk di bawah tekanan ekstrem, atau 2) patuh di bawah tekanan ekstrem, atau 3) mencari jalan memutar” terasa seperti gambaran suasana kerja yang sulit dibayangkan

    • Pengalaman pahit saya adalah bahwa hampir semua tempat kerja yang saya alami sejak 2008 memang seperti itu
  • Saya rasa jemalloc adalah satu-satunya allocator di macOS yang bisa melakukan override malloc/free semulus LD_PRELOAD (setidaknya sekitar 2020). Ia bisa dengan mudah masuk sebagai allocator default lewat pendekatan berbasis zone, dan juga cocok dengan persyaratan allocator khas Apple. Banyak allocator pihak ketiga lain sering gagal karena persyaratan ini

    • Namun, pendekatan ini hanya bisa bekerja dengan asumsi bahwa allocator sistem macOS tidak mengubah struktur internalnya, jadi saya ingat ada kira-kira dua kali kasus ketika Apple mengubahnya dan semuanya rusak

    • Setahu saya mimalloc juga bisa bekerja dengan cara yang sama, meski saya tidak yakin

  • Saya melihat jemalloc lebih baik daripada malloc glibc dalam segala hal, dan dari hasil benchmark pun tampaknya selalu menunjukkan performa yang lebih baik; jadi sebagai orang luar saya penasaran, kalau begitu kenapa ia bukan allocator default?

    • Di FreeBSD, jemalloc memang sudah jadi default. Kalau ingin mengganti malloc, lebih mudah sekalian mengganti libc dengan FreeBSD libc, dan kalau begitu wajar juga kernel-nya sekalian diganti ke FreeBSD. Ketika perusahaan kami bergabung dengan Facebook, saya sempat bersemangat memperkenalkan jemalloc ke rekan-rekan, tetapi karena mereka sudah memakai FreeBSD, di sana jemalloc dianggap sesuatu yang sangat wajar

    • Saya bukan engineer allocator jadi ini bukan pendapat ahli, tetapi dulu saya pernah berbicara dengan engineer yang mengelola allocator OS. Menurut dia, allocator kustom cenderung membuat satu proses menjadi sangat diuntungkan dalam alokasi memori, tetapi mengorbankan fairness alokasi di tingkat sistem secara keseluruhan. Dari sudut pandang allocator sistem, kalau tiap proses membawa pola yang berbeda-beda, optimasi global jadi lebih sulit. Itulah sebabnya di banyak lingkungan layanan, jemalloc sering direkomendasikan dengan asumsi “yang penting proses saya sekarang”

    • Saya tidak merasa ada alasan teknis yang membuat jemalloc tidak bisa menjadi allocator default. Faktanya, di FreeBSD memang itu yang dipakai secara default (seperti disebut dalam artikel). Menurut pemahaman saya, isu ini lebih bersifat politis daripada teknis

    • jemalloc sudah terbukti di produksi skala besar, lisensinya sangat permisif, dan performanya juga terbukti. Jadi saya sungguh penasaran apa sebenarnya alasan tetap bertahan dengan glibc malloc; selain “kemurnian ideologis” dan inersia warisan lama, siapa sebenarnya yang diuntungkan dari keadaan ini? Saya juga ingin mempertanyakan kenapa orang masih terus berlindung di balik alasan “kompatibilitas”

    • Dulu, masalah besar pada allocator alternatif adalah bahwa memori yang sudah free tidak pernah benar-benar dikembalikan ke OS dan hanya ditahan sebagai dirty page (ini akhirnya membaik, tetapi menjadi contoh khas perbedaan prioritas antar-allocator). Dan pada kenyataannya, sebagian besar proses hanya menjalankan satu main thread atau nyaris hanya punya thread yang idle. Allocator yang dioptimalkan untuk multithreading bisa jadi berlebihan dan malah menjadi beban di lingkungan seperti itu. Sebagai catatan, banyak orang juga tidak memikirkan bahwa biaya kernel untuk melakukan zero pada halaman memori dan biaya proses pengguna untuk melakukan zero demi reuse internal secara praktis tidak jauh berbeda

  • Saya justru berharap tautan tulisan blog itu ditambahkan ke repositori github. Menurut saya penting agar orang-orang yang nanti mengunjungi repo bisa mengetahui konteks ini dan menjadikannya referensi