9 puan yazan GN⁺ 2025-06-14 | 2 yorum | WhatsApp'ta paylaş
  • jemalloc geliştirmesine öncülük eden Jason Evans’ın doğrudan kaleme aldığı bu retrospektif yazı, yaklaşık 20 yıla yayılan jemalloc geliştirme yolculuğunu 5 aşamaya ayırarak; başarıları, başarısızlıkları, açık kaynak projelerin sınırlarını ve şirket içi değişimlerin yol açtığı gerileme sürecini samimiyetle kaydediyor
  • jemalloc bellek ayırıcısı, 2004’ten başlayarak yaklaşık 20 yıl boyunca yaygın şekilde kullanıldı; ancak son dönemde Meta içindeki değişimler nedeniyle resmî geliştirme durdu
  • İlk FreeBSD entegrasyonu, Firefox performans sorunlarının çözülmesi ve Facebook’un büyük ölçekli benimsemesi gibi çeşitli aşamalarda performans optimizasyonu ve portlama deneyimi birikti
  • Depolama alanı parçalanması sorunu ve ölçeklenebilirlik problemleri gibi çeşitli zorluklar aşılırken, performans iyileştirmelerinin yanı sıra istatistik toplama, test altyapısı gibi birçok özellik eklendi
  • Meta’daki şirket kültürü değişimiyle birlikte teknik yatırımın azalması, çekirdek bakım ekibinin yokluğu nedeniyle uzun vadeli geliştirme durdu
  • Valgrind’in kaldırılması ve dış kullanıcı geri bildiriminin eksikliği gibi etkenler, açık kaynak ekosistemindeki kopukluğun yapısal sınırlar olarak işlemesine neden oldu
  • Gelecekte fork yoluyla yeni gelişim olasılığı açık olsa da, resmî ana geliştirme hattının artık devam etmesi beklenmiyor

jemalloc’a genel bakış

  • jemalloc, 2004’te ilk kez tasarlanmış bir açık kaynak bellek ayırıcısıdır; performans ve ölçeklenebilirliği artırma hedefiyle geliştirildi ve 20 yıl boyunca başlıca açık kaynak projelerde ve büyük teknoloji altyapılarında aktif biçimde kullanıldı
  • Ana geliştirme yakın zamanda durdu; bundan sonra fork’lar veya kurum bazlı bakım bekleniyor

Phase 0: Lyken

  • 2004’te bilimsel hesaplama için geliştirilen Lyken adlı programlama dili sürecinde, elde yazılmış bir bellek ayırıcıyla başlandı
  • Lyken içindeki ayırıcı, 2005 Mayıs’ında işlevsel olarak tamamlandı
  • Ayırıcı daha sonra FreeBSD’ye entegre edilince, Lyken tarafında yalnızca sistem ayırıcısına ince bir wrapper bırakılıp kaldırıldı
  • Kaldırılma nedeni, FreeBSD entegrasyonundan sonra sistem ayırıcısında eksik kalan kısmın yalnızca belirli bir ihtiyaç olarak netleşmesi oldu: thread başına tahsis miktarını izleme
  • İlginç biçimde, daha sonra Lyken döneminde ihtiyaç duyulan istatistik toplama özelliği jemalloc’a eklendi

Phase 1: FreeBSD

  • 2005’te çok işlemcili bilgisayarlar yaygınlaşırken FreeBSD, phkmalloc kullanıyordu; ancak bu, paralel thread ortamları için uygun değildi
  • Lyken ayırıcısı ölçeklenebilirlik açısından açık avantaj sunduğu için FreeBSD’ye entegre edildi ve kısa süre sonra jemalloc adını aldı
  • Ancak KDE uygulamalarında ve benzer yerlerde ciddi parçalanma sorunları ortaya çıktı; bu da yaşama şansını sorgulattı
  • Parçalanmanın nedeni, boyuta göre ayrım yapmayan birleşik alan tahsis yöntemiydi; araştırmaların ardından yapı, boyuta göre bölge ayıran algoritma ile köklü biçimde değiştirildi
  • Sürecin ayrıntıları 2006 BSDCan makalesinde kayda geçirildi

Phase 1.5: Firefox

  • 2007’de Mozilla Firefox 3 yayımlanmak üzereyken, Windows ortamındaki bellek parçalanması büyük bir sorundu
  • jemalloc’u Linux’a port etmek kolaydı, ancak Windows zorluydu
  • FreeBSD libc içinde bulunan jemalloc, Mozilla tarafından fork edilerek taşınabilirlik ve uyumluluk geliştirmeleri yapıldı
  • Zaman içinde Mozilla, jemalloc upstream’ine birçok iyileştirme katkısı sundu; ancak fork sürümünün performansı her zaman daha yüksekti
  • Bunun performans regresyonlarından mı yoksa belirli ortamlara özel optimizasyonlardan mı kaynaklandığı net değil

Phase 2: Facebook

  • 2009’da Facebook’a katıldığında, jemalloc’un en büyük engeli araç eksikliğiydi; özellikle profilleme ve sızıntı tespiti
  • Bunu gidermek için jemalloc 1.0.0 ile pprof uyumlu heap profiling özelliği eklendi
  • Geliştirme GitHub’a taşındıktan sonra kullanıcılar ve dış katkıcılarla birlikte test altyapısı, Valgrind desteği, JSON istatistikleri, yeni sayfa yönetimi gibi birçok iyileştirme yapıldı
  • İçeride ise Facebook’un devasa telemetri sistemi, performans optimizasyonu ve regresyonların önlenmesinde büyük fayda sağladı
  • 3.x: test altyapısı ve Valgrind desteği eklendi
  • 4.x: decay tabanlı bellek temizleme (decay-based purging), JSON istatistikleri eklendi
  • 5.x: tasarım chunk’tan extent tabanlı yapıya geçirildi; 2MiB huge page kullanımının temeli atıldı
  • Facebook içindeki telemetry tabanlı performans analizi, optimizasyonlarda belirleyici rol oynadı
  • 5.0.0 sürümünde Valgrind desteğinin kaldırılması, içeride kullanılmaması nedeniyle kararlaştırıldı; ancak Rust geliştiricileri gibi dış kullanıcılar güçlü tepki gösterdi
  • Sonrasında Facebook/Meta’daki organizasyonel değişimler nedeniyle jemalloc ekibi küçüldü ve iş stratejisi, çekirdek teknik yatırımdan çok verimlilik odaklı hâle geldi
  • Bunun sonucunda Huge Page Allocation gibi büyük özelliklerin geliştirilmesi yavaşladı ve bazı çalışmalar tamamlanamadı
  • Evans’ın 2017’de ayrılmasının ardından, geliştirme birkaç yıl boyunca Qi Wang öncülüğünde sürdü
  • Ekip liderliği devredildikten sonra da çeşitli katkıcılar projeyi ayakta tuttu; ancak uzun vadeli vizyonu yöneten bir sahip artık kalmadı

Phase 4: Stasis (durgunluk)

  • Şu anda jemalloc upstream geliştirmesi sona ermiş durumda; Meta da kendi iç ihtiyaçlarına göre ayrı bir yön izliyor
  • Mevcut kod tabanındaki teknik borç büyük olduğu için önce kapsamlı bir refactoring gerekiyor
  • Facebook/Meta’nın gereksinimleri ile dış kullanıcıların gereksinimleri artık örtüşmüyor
  • Gelecekte geliştirme yeniden başlayacaksa, önce yüzlerce saatlik teknik borç temizliği yapılması gerekecek; yazarın ise buna isteği yok
  • dev branch’i veya 5.3.0 temel alınarak haricî fork yapılabilir; dolayısıyla fork tabanlı yeni bir projenin ortaya çıkma ihtimali her zaman var

Geriye bakış ve çıkarılan dersler

  • Valgrind desteğinin kaldırılması sonrası yaşanan çatışma, dış kullanım alanlarının yeterince bilinmemesinden kaynaklandı
  • jemalloc’un Android’de kullanıldığının ancak 2 yıl sonra öğrenilmesi de buna örnek oldu
  • Proje GitHub’da tamamen açık olmasına rağmen, dış kurumlardan gelen çekirdek katkıcılar kalıcı olamadı
    • Firefox’tan Mike Hommey’nin katkıları ya da CMake’e geçiş denemesi de sonuçta yarım kaldı
  • Deneyim gösterdi ki, bir projeyi yalnızca açık hâle getirmek onun sürdürülebilir bağımsız bir proje olmasını sağlamıyor
  • Açık kaynak yalnızca yayımlanmakla ayakta kalmaz; çekirdek katkıcı yetiştirmek ve yönetişim oluşturmak zorunludur

Kapanış

  • jemalloc, 25 yılı aşkın süredir çöp toplama savunucusu olan yazar için bile özel bir deneyimdi
  • Şimdi yeniden çöp toplama sistemleri geliştirmeye odaklanıyor; ancak jemalloc’a katkı veren herkese derin teşekkürlerini iletiyor

2 yorum

 
ganadist 2025-06-14

Tam metnin çevirisi de mevcut.
https://rosettalens.com/s/ko/jemalloc-postmortem

 
GN⁺ 2025-06-14
Hacker News yorumu
  • Upstream deposunu arşivleme kararını anlıyorum. Meta'dan ayrılmadan önce Jemalloc ekibimizin GitHub'a gelen her türlü issue'ya yanıt verecek kapasitesi yoktu. Örneğin biri Itanium ortamında testlerin geçmediğine dair issue açmıştı; bu bana biraz komik gelmişti. Yine de bu durumu görmek üzücü. Hâlâ jemalloc'un, bence genel amaçlı malloc uygulamaları arasında hem en yüksek performansı sunan hem de kullanımı en kolay seçenek olduğunu düşünüyorum. TCMalloc da harika, ama bazel kullanmıyorsanız gerçekten çok zor bir seçenek bence. Bugünlerde bazel 7.4.0'a cc_static_library eklendiği için statik kütüphane olarak dışa aktarmak biraz daha kolaylaştı, ama bu sorun hâlâ anlamlı ölçüde sürüyor. Qi'ye, depoyu yeniden arşivlemeden önce son bir 6.0 sürümü çıkarıp çıkaramayacağını sormaya niyetliyim. Son sürüm olacaksa varsayılan ayarları biraz modernleştirmek iyi olabilir. Örneğin adıyla uyumsuz biçimde kafa karıştıran cache oblivious ayarını varsayılanda kapatmak, 16 KiB size-class'ın gereksiz yere 20 KiB'e şişmesini engelleyeceği için büyük bir iyileştirme olur. Önceki seçimi, yani Jason'ın ilk kararını eleştirmek istemiyorum; o dönemde bunu Qi ve David ile konuştuğumuzda TLB associativity'nin genel olarak bugünkünden çok daha düşük olması makul bir gerekçeydi. Benzer şekilde varsayılan page size'ı 4 KiB'den daha büyük bir değere, mesela 16 KiB'e çıkarmak da iyi bir değişiklik olurdu. Böylece büyük size-class eşiği, yani birden fazla tahsisi slab'e yerleştirirken belli bir boyutun üstünde her birini ayrı aralıklara tahsis etmeye geçilen nokta, 16 KiB'den 64 KiB'e çıkar ve etkisi büyük olur. Meta'dan ayrılmadan önce bunu büyük bir iç serviste uygulamayı son kez değerlendirmiştim; RAM parçalanmasından kaynaklı küçük bir bellek artışı karşılığında CPU kullanımında birkaç puan düşüş sağlayan bir optimizasyondu. Bunun dışında da değiştirmek istediğim birkaç şey var; örneğin metadata_thp varsayılanını disabled yerine auto yapmak, slab'lerin extent boyutlandırmasını sayfa boyutunun tam katları yerine yaklaşık %1 israfa izin verip parçalanmayı azaltacak şekilde değiştirmek gibi. Ama en büyük değişiklikler yine yukarıda bahsettiğim ayarlar olurdu

    • Itanium test paketi başarısızlığı issue'sunu açan kişi bendim

    • İnsanların Hacker News'e dönüp durmasının sebebi tam da böyle gerçek deneyimler ve içeriden gelen içgörüler bence. TCMalloc'u bazel olmadan kullanmanın neden zor olduğunu merak ediyorum; bunu gerçekten samimiyetle soruyorum

    • Bu kadar önemli iç bilginin resmî dokümanlar ya da blog yazıları gibi daha kapsamlı kaynaklarda yayımlanmasını isterdim. Şu anda resmî dokümantasyon çok yetersiz geliyor. Meta içinde yapılan bunca çalışmanın birikimi zamanla kaybolmadan paylaşılsa keşke

    • Yazılım harika ama build ve entegrasyon süreci karmaşık olduğu için hak ettiği kadar iyi değerlendirilememesi üzücü

    • "Jemalloc ekibinin GitHub'a gelen rastgele issue'lara yanıt verecek yeterli kapasitesi yoktu" demişsiniz; bunu merak ediyorum. Meta'da bu projeyi yöneten yeterli sayıda insan olmasına rağmen issue yönetiminin neden düzgün işlemediğinin arka planı neydi? Eğer durumu yanlış anladıysam lütfen düzeltin

  • Jason'ın çalışmasının işlerimiz üzerindeki etkisinin ne kadar büyük olduğunu anlatmak istiyorum. Şirketimiz her gün yüz milyonlarca görsel ve videoyu işleyen oldukça büyük ölçekli bir yapı. İlk birkaç yılda bellek parçalanması yüzünden inanılmaz sıkıntı çektik. Sonra bir gün jemalloc'u devreye aldık ve Dockerfile'da sadece iki satır değiştirerek bütün sorunları çözdük. Bugün milyarlarca gelir üreten bir şirketiz ve tüm servislerimizde, tüm Dockerfile'larımızda jemalloc kullanıyoruz. Bunun için içtenlikle teşekkür ederim

    • Pratikte birçok golang tabanlı görsel işleme servisi jemalloc'u öneriyor ya da kullanıyor. resize-images konusundaki ilk 3 servis baz alındığında (2025-06-13 itibarıyla), imaginary bunu Dockerfile'da şu şekilde kullanıyor; imgproxy ise arşivlenmiş belgede geçiyor ve imaginary reposunda da tartışılıyor. imagor da şurada jemalloc kullanıyor

    • Bunu gerçekten samimiyetle soruyorum, alay etmek için değil: bağış da yaptınız mı? Sonuçta parayla teşekkür etmek en iyi minnettarlık ifadesi değil mi?

  • "jemalloc'un Rust ikililerinden beklenenden hızlı çıkarıldığı" yorumuna ilişkin olarak, aslında o issue'nun birçok nedenden sadece biri olduğunu belirtmek isterim. Bu yorumda ilgili arka plan görülebilir. Ayrıca jemalloc'un tamamen kaldırılması, o issue ilk gündeme geldikten tam iki yıl sonra oldu (bkz. bu PR)

    • Orada geçen çeşitli issue'lar arasında arm64'te sabit kodlanmış sayfa boyutu sorununun hâlâ upstream'de çözülmemiş olması ilginç. Bu yüzden uygulama geliştiricilerinin birden fazla ayrı arm64 Linux ikilisi dağıtması ya da bazı platformlardan vazgeçmesi gerekiyor. Dinamik sayfa boyutu, yani performans için ftrace tarzı ikili yama uygulamasını çalışma anında yapmak, kullanılsaydı acaba ne kadar daha yavaş olurdu diye merak ediyorum
  • Yıllardır geliştirdiğim her oyun motorunda jemalloc kullanmayı alışkanlık hâline getirdim. win32 ortamında varsayılan allocator'dan çok daha hızlı ve tüm platformlarda aynı allocator'ı kullanmanın da büyük avantajı var. FreeBSD'de jemalloc'un entegre olduğunu görünce haberdar olmuştum; o zamandan beri hep jemalloc kullanıyorum. Jemalloc sayesinde birçok oyuncunun daha iyi bir deneyim yaşadığını düşünmek bana gurur veriyor

    • Windows'un varsayılan allocator'ı gerçekten kötü. Jemalloc en iyisi
  • Güzel bir yazı — Facebook'un, yani bugünkü adıyla Meta'nın, artık jemalloc'u kendisinin kullanmadığını mı yoksa sadece bakımını mı sürdürdüğünü merak ediyorum. Belki tcmalloc'a ya da başka bir allocator'a geçmiş olabilirler mi? "Facebook altyapı mühendisliğinde vurgu, çekirdek teknoloji yatırımlarından çok ROI odaklılığa kaydı" diye bir cümle vardı

    • Meta'dan ayrıldığım dönem neredeyse iki yıl önceydi, ama büyük bir değişiklik olduğunu sanmıyorum; jemalloc hâlâ Meta içindeki tüm ikililere statik olarak linklenmiş durumda. tcmalloc'a ya da başka bir allocator'a kolayca geçilip geçilemeyeceğine gelirsek, jemalloc şirket içi ekosisteme çok derinden bağlı olduğu için düşündüğünüz kadar kolay değil. Strobelight telemetri altyapısından jemalloc'a göre yazılmış çok sayıdaki extension'a, örneğin doğrudan özel extent hook kullanan manuel arena'lara kadar her şey buna bağlı; ayrıca uygulamaların çoğu da zaman içinde jemalloc'un özelliklerinden en yüksek verimi alacak şekilde evrilmiş durumda

    • Son dönemdeki en büyük değişiklik, jemalloc'un uzun süreli ana maintainer'larının artık ayrılmış olması. Ama ilginç biçimde Facebook içinde bu projeye eskisine göre daha fazla ilgi oluşmaya başladı ve son zamanlardaki bazı tartışmalı issue'lardan sonra işlerin hem Qi ve Jason'ı hem de dış kullanıcıları gözeten bir yöne gidebileceğine dair olumlu bir beklentim var

    • Meta hâlâ kendi fork'unu burada aktif olarak geliştiriyor

  • Firefox'tan Facebook'a kadar uzun bir döneme yayılan bu etkili işin bir parçası olabilmiş olmak benim için onurdu

    • Ben de doğru zamanda teşekkür bırakmak istiyorum. Bu yazının bugün yayımlanacağını beklemiyordum ama bu uzun yolculuğun küçük bir parçası olabilmiş olmak benim için onurdu. @je, qi, david'e ve o dönemde ya da sonrasında katkı sunan herkese teşekkürler

    • Facebook içinde çekirdek teknolojilere yatırımın sürmesini sağlayan liderliğinizin gerçekten büyük sonuçlar verdiğini düşünüyorum. GraphQL, PyTorch ve React gibi yeniliklerin ortaya çıkabilmesinde bunun önemli payı vardı

  • "İmkânsız seçeneklerle karşı karşıya kalan insanlar ya 1) aşırı baskı altında kötü kararlar verir, ya 2) aşırı baskı altında boyun eğer, ya da 3) etrafından dolaşır" şeklindeki FTA alıntısı, bir iş ortamı için hayal etmesi bile zor bir tablo çiziyor

    • 2008'den beri çalıştığım neredeyse bütün iş yerleri maalesef tam olarak böyleydi
  • 2020 civarı itibarıyla jemalloc'un, macOS'ta malloc/free'yi LD_PRELOAD benzeri şekilde sorunsuz override edebilen tek allocator olduğunu düşünüyorum. zone tabanlı yöntemle kolayca varsayılan allocator gibi araya girebiliyor ve Apple'a özgü allocator gereksinimlerini de iyi karşılıyordu. Diğer üçüncü taraf allocator'lar bu gereksinimler yüzünden sık sık başarısız oluyordu

    • Ama bu yaklaşım, macOS sistem allocator'ının iç yapısını değiştirmeyeceği varsayımına bağlı; hatırladığım kadarıyla Apple bunu değiştirip iki kez bozmuştu

    • mimalloc da sanırım aynı şekilde çalışabiliyor, ama emin değilim

  • Benchmark sonuçlarına bakınca jemalloc'un glibc malloc'a göre her açıdan daha iyi göründüğünü ve sürekli daha yüksek performans verdiğini biliyorum; o hâlde neden varsayılan allocator olmadığını dışarıdan biri olarak hep merak ettim

    • FreeBSD'de zaten varsayılan olarak jemalloc kullanılıyor. malloc'u değiştirmek istiyorsanız libc'yi de FreeBSD libc ile değiştirmek daha kolay olurdu; o noktada çekirdeği de FreeBSD yapmak mantıklı olurdu. Facebook ile birleştiğimizde bir çalışma arkadaşımıza jemalloc'u heyecanla anlatmıştım ama zaten FreeBSD kullandıkları için bu onlar için son derece olağandı

    • Ben allocator mühendisi değilim, o yüzden uzman görüşü sayılmaz ama yıllar önce bir OS allocator mühendisiyle konuşmuştum. Ona göre özel allocator'lar tek bir sürece bellek tahsisinde büyük avantaj sağlayabiliyor ama sistem genelinde tahsis adaletini kötüleştirme eğiliminde. Sistem allocator'ı açısından, her süreç farklı bir desen izleyince tüm sistem için optimum davranış zorlaşıyor. Bu yüzden hizmet ortamlarının çoğunda, "şu anda önemli olan yalnızca benim sürecim" varsayımı altında jemalloc sık öneriliyor

    • Jemalloc'un varsayılan allocator olmamasının teknik bir sebebi olduğunu sanmıyorum. FreeBSD'de zaten varsayılan; makalede de geçiyor. Benim anladığım kadarıyla bu konu teknikten çok politik

    • Jemalloc gerçek büyük ölçekli üretim ortamlarında kanıtlanmış, lisansı çok serbest ve performansı da açıkça ortada. Buna rağmen glibc malloc'ta ısrar edilmesinin sebebi ne, "ideolojik saflık" ve eski alışkanlıklar dışında bundan kim fayda görüyor gerçekten merak ediyorum. Neden hâlâ "uyumluluk yüzünden" denilerek savunuluyor, anlamakta zorlanıyorum

    • Eskiden alternatif allocator'ların önemli bir sorunu, serbest bırakılan belleği OS'ye geri vermeyip kirli sayfa olarak elde tutmalarıydı. Bu sonradan iyileşti ama allocator önceliklerinin ne kadar farklı olabildiğini gösteren iyi bir örnekti. Ayrıca gerçekte süreçlerin çoğu sadece ana thread'i çalıştırıyor ya da diğer thread'ler neredeyse tamamen boşta oluyor. Çok iş parçacıklı ortamlara optimize edilmiş allocator'lar böyle durumlarda gereksiz karmaşıklık ve yük getirebiliyor. Bir de çoğu kişinin, sayfaları sıfırlama işini çekirdeğin yapmasının maliyetiyle, kullanıcı sürecinin iç yeniden kullanım için bunu kendisinin yapmasının maliyeti arasında pratikte büyük bir fark olmadığını pek düşünmediğini eklemek isterim

  • Keşke blog yazısı bağlantısı GitHub deposuna da eklense. Bundan sonra repoyu ziyaret edenlerin bu bağlamı görmesi ve başvurabilmesi önemli olurdu bence