LMAX'taki ekip neden Java kullanıyor ve GC'yi ne pahasına olursa olsun mimariyi tasarladı?


24

Neden LMAX’taki ekip Java’daki LMAX Yıkıcı’yı tasarladı ama bütün tasarımları GC kullanımını minimuma indirdi ? Eğer biri GC çalıştırmak istemiyorsa, neden bir çöp toplanmış dil kullanıyorsunuz?

Optimizasyonları, donanım bilgisi seviyesi ve ortaya koydukları düşünce sadece harika ama neden Java?

Java ya da herhangi bir şeye karşı değilim ama neden bir GC dili? Neden GC veya D gibi bir dil kullanmıyorsunuz, ancak etkin kod veriyorsunuz? Ekibin Java ile en aşina olduğu mu yoksa Java göremediğim benzersiz bir avantaja sahip mi?

Manuel bellek yönetimi ile D kullanarak geliştirdiklerini söyleyin, fark ne olurdu? Düşük seviyede (zaten oldukları gibi) düşünmek zorunda kalacaklardı, ancak sistemdeki en iyi performansı doğal olduğu için sıkıştırabilirler.


6
Bu proje hakkında çok az şey biliyorum, ancak başkalarının üzerine inşa edebileceği bir tür çerçeve gibi görünüyor. Ve eğer bunu Java’ya yazmayı başarırsanız (ve başkalarının Java’da kodlamasını sağlayın ve avantajlardan yararlanın), o zaman D’de yazdığınızdan çok daha büyük bir “müşteri tabanına” sahip olacaksınız.
Joachim Sauer

6
@kadaj: Tüketici halka açık mı yoksa dahili mi olursa olsun gerçekten önemli değil: eğer yaygın olarak bilinen bir dilde erişilebilir yaparsanız, içsel gelişim için bile daha faydalı olacaktır. (Varsayımsal) tartışmanıza şu şekilde başlarsanız: "Herkesin Java'yı bildiği kadar D'yi de bildiğini varsayın ...", o zaman muhtemelen bir şeyleri kaçırıyorsunuzdur.
Joachim Sauer

6
Bazı insanlar her türlü problem için çekiç kullanmaktan hoşlanırlar. Planlamak istediğiniz kaba bir kenarı var, pürüzsüz olana kadar çekiçle bastırın. İhtiyacınız olan bir vidaya sahip olun, içeriye kadar bir çekiçle bastırın. Zımparalamanız gereken hassas bir süsleme yapın, bir çekiçle bastırın ve sonra "emme" için süsleme yapın. C veya C ++, sadece mevcut bilgi tabanı için, D'den daha iyi bir seçim olabilirdi. D'yi neden örnek bir TBH olarak gösterdiğinden bile emin değilim.
gbjbaanb

2
@gbjbaanb D'den bahsettim, çünkü çöp toplama sağlıyor (yüksek seviyeli soyutlamaların gerekli olduğu ve hafızayla karıştırmanın beyin için çok zor olduğu durumlarda), ancak aynı zamanda C tarzı malloc ile serbest hafıza yönetimi de sağlıyor. D, ARC'li (gerçek GC yok) fakat bundan daha iyi olan Objective-C türüne benzer. Ama evet, C / C ++ faturaya uyuyor.

4
@kadaj D'yi büyütmek için burada biraz flakallaştığını görüyorum ama diğerlerinin kullandığı tonda hayal kırıklığına uğradığımı ve D'nin eldeki sorunun merkezinde olduğunu düşündüğümü söylemek istiyorum. D gerçekten yaygın olarak kullanılmamakla birlikte, D, Java veya C # kelimesinde bulmayı umduğum, (en azından eski tip) C ++ 'da bulabileceğim bazı üst düzey yapılar sunmaktadır. Hala yönetilen ve yönetilmeyen bir karışım sağlar - ki bunu yapmayı bildiğim tek dil budur! D sadece evcil hayvan tercihi değil, GC etrafındaki orijinal sorularla örtüşen hedefleri olan bir seçenektir.
J Trana

Yanıtlar:


20

Çünkü performansı optimize etmek ve tamamen güvenliği kapatmak arasında çok büyük bir fark var.

GC sayısını azaltarak, onların çerçevesi daha duyarlıdır ve (muhtemelen) daha hızlı çalışabilir. Artık, çöp toplayıcı için en iyi duruma getirme, hiçbir zaman çöp toplama işlemi yapmadıkları anlamına gelmez. Sadece daha az sık yaptıkları ve bunu yaptıkları zaman çok hızlı çalıştıkları anlamına geliyor. Bu tür bir optimizasyon şunları içerir:

  1. Küçük fırlatma nesneleri kullanarak hayatta kalan bir alana (yani en az bir çöp toplama işleminde hayatta kalan) hareket eden nesne sayısının en aza indirilmesi. Hayatta kalan alana taşınan nesnenin toplanması daha zordur ve çöp toplanması bazen JVM'nin dondurulması anlamına gelir.
  2. Başlamak için çok fazla nesne ayırmayın. Bu, dikkatli olmamanız durumunda geri tepebilir, çünkü genç kuşak nesneler tahsis etmek ve toplamak süper ucuzdur.
  3. Yeni nesnenin eskisine işaret etmesini sağlayın (tersi yönde değil), böylece genç nesnenin toplanmasının kolay olmasını sağlar, çünkü onların tutulmalarına neden olacak hiçbir referans yoktur.

Performansı ayarladığınızda, genellikle çalışmayan bir kodu görmezden gelirken, genellikle çok özel bir "sıcak nokta" ayarlarsınız. Bunu Java'da yaparsanız, çöp toplayıcının, dar bir döngüde çalışan alan için çok dikkatli bir şekilde optimizasyon yaparken (çok fazla fark yaratmayacağından), o karanlık köşeyle ilgilenmesine izin verebilirsiniz. Böylece, nerede optimize edeceğinizi ve nerede istemediğinizi seçebilir ve böylece çabanızı önemli olan yere odaklayabilirsiniz.


Şimdi, tamamen çöp toplama işlemini kapatırsanız, seçim yapamazsınız . Her nesneyi manuel olarak elden çıkarmalısınız . Bu yöntem günde en fazla bir kere çağrılıyor mu? Java'da, performansının etkisi göz ardı edilebileceği için izin verebilirsiniz (her ay tam bir GC gerçekleşmesine izin vermek uygun olabilir). C ++ 'da hala kaynak sızdırıyorsunuz, bu yüzden bu belirsiz metoda bile dikkat etmeniz gerekiyor. Bu nedenle , uygulamanızın her bir bölümünde kaynak yönetimi için ücret ödemeniz gerekir , oysa Java'da odaklanabilirsiniz.


Ama daha da kötüleşiyor.

Ya bir hatanız varsa, uygulamanızın yalnızca Pazartesi günü dolunayda erişilen karanlık bir köşesinde diyelim mi? Java'nın güçlü güvenlik garantisi vardır. "Tanımlanamayan davranış" yok denecek kadar az şey var. Yanlış bir şey kullanırsanız, bir İstisna atılır, programınız durur ve veri bozulması olmaz. Yani farketmeden yanlış bir şey olamayacağından eminsin.

Ancak D gibi bir durumda, kötü bir işaretçi erişimine veya arabellek taşmasına sahip olabilirsiniz ve belleğinizi bozabilirsiniz, ancak programınız bilmeyecek (güvenliği kapattınız, hatırladınız mı?) Ve hatalı çalışmaya devam edecek veri ve bazı kötü şeyler yapmak ve verilerinizi bozmak ve bilmiyorsunuz ve daha fazla yolsuzluk olur, verileriniz gittikçe daha yanlış olur ve sonra aniden kırdı ve hayat kritik bir uygulamadaydı ve bazı hata bir roketin hesaplamasında oldu ve değil işi ve roket patlayabilir ve birisi kalıp, yapar ve şirket her gazetenin ön sayfasında yer almaktadır ve patronunuz noktası olan parmak yüzden size söyleyerek "Sen vardır performansı optimize etmek için D'yi kullanmamızı öneren mühendis, neden güvenliği düşünmediniz?". Ve bu senin suçun. Bu insanları aptalca gösteri girişimlerinde öldürdün.


Tamam, tamam, çoğu zaman bundan daha az dramatik. Ancak işle ilgili kritik bir uygulama veya yalnızca bir GPS uygulaması veya bir hükümet sağlık web sitesi bile, eğer sorunlarınız varsa oldukça olumsuz sonuçlar doğurabilir. Bunları tamamen engelleyen veya gerçekleştiğinde hızlı bir dil kullanmak genellikle çok iyi bir fikirdir.

Bir güvenliği kapatmanın bir bedeli vardır. Yerli olmak her zaman mantıklı olmaz. Bazen, kendinizi en iyi şekilde ayağınıza vurabileceğiniz bir dilde kullanmak için biraz güvenli bir dili optimize etmek çok daha basit ve daha güvenlidir. Bir çok durumda doğruluk ve güvenlik, GC'yi tamamen ortadan kaldırarak hurdaya ayıracağınız birkaç nano saniyeyi aşmaktadır. Engelleyici aygıtı olabilir ben LMAX-Değişim doğru kararı düşünüyorum bu yüzden, bu durumda kullanılabilir.

Peki ya özellikle D? Karanlık köşeler için isterseniz bir GC'niz var ve SafeD alt kümesi (düzenlemeden önce bilmediğim) tanımsız davranışları kaldırıyor (kullanmayı hatırlıyorsanız!).

Bu durumda basit bir vade sorusu. Java ekosistemi iyi yazılmış bir araç ve olgun kütüphanelerle doludur (gelişim için daha iyidir). Çok daha fazla geliştirici Java'yı D'den daha çok biliyor (bakım için daha iyi). Finansal bir uygulama kadar kritik bir şey için yeni ve popüler olmayan bir dilin kullanılması iyi bir fikir olmazdı. Az bilinen dilde, eğer bir probleminiz varsa, çok azı size yardımcı olabilir ve bulduğunuz kütüphanelerde daha az insana maruz kaldıklarından daha fazla böcek olabilir.

Bu yüzden son noktam hala geçerli: Korkunç sonuçları olan sorunlardan kaçınmak istiyorsanız, güvenli seçimlerle devam edin. D'nin hayatındaki bu noktada, müşterisi çılgın risk almaya hazır küçük girişimlerdir. Bir problem milyonlara mal olabilirse, inovasyon zili eğrisinde daha iyi olursunuz .


2
Orijinal yazı özellikle D'yi söyler. Aslında, seçimin ayrıntı düzeyi konusunda C ++ ve D arasında oldukça büyük bir fark var. SafeD alt kümesinde tam olarak yönetilmeyi tercih etseniz bile, toplama ve zamanlamanın belirli yönleri üzerinde biraz daha kontrol sahibi olacağınızı düşünüyorum (etkinleştir / devre dışı bırak, topla, küçült). Check out bellek yönetimi için Dijital Mars'ın stratejileri!
J Trana

2
Imax kasten Java'nın sağladığı bazı güvenlik önlemlerinin bir kısmını
James

Java kritik görev yazılımı için lisanslı olmadıkça, bu harika bir cevap olacaktır. Eğer bir nükleer reaktörünüz varsa, tüm "güvenlik" yönünü ortaya çıkaran Java değil, C ++ dilinde yazılacaktır.
gbjbaanb

@gbjbaanb, [alıntı gerekli]. Gördüğüm güvenilirlik standartları / kılavuzları ilk önce diğer dillerin lehine C / C ++ 'dan kaçınılmasını öneriyor ; ve eğer onların içine giriyorsa, o zaman dillerin son derece sınırlı versiyonlarını kullanmak (MISRA, vb.). Kısıtlamaları kabul ettiğinizde, başka bir dilde neden aynı şeyi yapamadığınızı anlamıyorum. Eğer Java Licence'ın “SINIRLAMALAR” bölümünde “nükleer tesisler için değil” denmesinden bahsediyorsanız, bir süre önce değişmiş gibi görünüyor ve şimdi bunun yerine “bizim sorumluluğumuz değil dikkatli olun” gibi bir şey söylüyor. Yine de, (...)
hmijail

(...) orijinal metinler tıpkı gcc ve clang'ın lisansları gibiydi: herhangi bir özel amaç için hiçbir garanti yok. Böylece, onları güvenilirliğe ihtiyaç duyan bir şey için kullanmazsınız ve bunun yerine, iş için belirli bir dile gitmiyorsanız, bazı sertifikalı derleyicileri kullanmanız gerekir (Ada?).
hmijail

4

Görünüşe göre, Java'da yazılmasının sebebi, kurum içinde Java uzmanlığına sahip olmaları ve C ++ C / 0/11 ile birlikte harekete geçmeden önce muhtemelen (hala aktif gelişimde olmasına rağmen) yazılmış olması.

Kodları gerçekten sadece Java ismiyle, sun.misc'yi kullanırlar.Güvenli bir şekilde Java'nın noktasını yenen ve güvenliğin sözde olduğu bir tür. Yıkıcı'nın bir C ++ portunu yazdım ve gönderdikleri Java kodundan daha iyi performans gösteriyor (JVM'yi ayarlamak için çok fazla zaman harcamak istemedim).

Bununla birlikte, bozucunun izlediği prensipler dile özgü değildir, örneğin yığıntan toplanan veya serbest bırakan düşük gecikmeli C ++ kodu beklemeyin.


Uygulamanızı işaret edebilir misiniz? Yüksek performans iddiasında bulunmak yerine bu tür birkaç yeniden uygulama gördüm, ancak her ikisi de sadeleştirmelerle aldatıldı: örneğin, orijinal Yıkıcı gibi yetenekli çoklu üretici / tüketici olmak yerine 1 üretici + 1 tüketiciyi donanımlamak. Yıkıcı'nın kendisi bir Google Grupları başlığında, Java sürümündeki donanım parametreleri ile performansın arttırılabileceğini belirtti.
hmijail

4

Bu soru gerçeği olarak yanlış bir öncül ifade eder, sonra bu yanlış öncül hakkında bir tartışma yapar.

Hadi şunu anlayalım .. "GC tasarımını en aza indirgemek için tüm tasarım noktaları" - sadece doğru değil. Yıkıcıdaki inovasyonun GC ile pek ilgisi yok. Yıkıcı, tasarımı, modern bilgisayarların nasıl çalıştığını zekice gördüğü için tasarlıyor, çünkü beklenenden çok daha az yaygın olan bir şey. Bir tartışma için Cliff Click'ın konuşmasına bakın http://www.azulsystems.com/events/javaone_2009/session/2009_J1_HardwareCrashCourse.pdf .

LMax'ın Azul müşterileri olduğu iyi bilinmektedir. İlk elden Azul GC’lerin 175 GB’lık yığınlarla bile bir uyumsuz olduğunu biliyorum.


Bunun için bir miktar doğruluk var. Büyük bir koleksiyondan kaçınmak için her gece VM'yi yeniden başlatırlar. Yine de Martin Fowler'ın yazdığı şey buydu ve kukla değildi: “Sistemin geri kalanı gibi, aksaklıklar bir gecede sıçradı. Bu sıçrama çoğunlukla hafızayı silmek için yapılır, böylece işlem sırasında pahalı bir çöp toplama olayının daha az şansı olur.” martinfowler.com/articles/lmax.html
JimmyJames

2
Tam değil. 5 dakikalık bir işlem aralığında her gece manuel bir GC tetiklerdik ve ayarladık, böylece gün içindeki tek büyük GC olacaktı. Bu Azul Zing ile gereksiz oldu. (Kaynak: Geçenlerde kadar Lmaks çalıştı)
Tom Johnson

@ TomJohnson iç kepçe almak seviyorum. Martin Fowler'in açıklamasının yanlış olduğunu mu söylüyorsunuz? Çözümün zaman içinde gelişmesi mümkün mü?
JimmyJames

2
Bazı küçük detaylarda tam olarak doğru olmadığını söylüyorum. Sistemlerimizi hiçbir zaman günlük olarak zıplatmadık, ancak günün sonunda bir temizlik yaptık.
Tom Johnson,

3

Düşük seviyede düşünmek zorunda kalacaklardı

Yukarıdaki, aradığınız cevabın yarısını yapar. Sebepleri tamamlamak için LMAX blog'undan daha uzakta olmayan başka bir yarısı bulabilirsiniz :

Çok verimli olmasına rağmen, vidalanması çok kolay olduğu için birçok hataya yol açabilir ...

LMAX geliştiricileri tarafından kabul edildiği gibi, böyle bir kodun Java'da bile geliştirilmesi, anlaşılması ve hata ayıklanması oldukça zor olabilir. Düşük seviyeli programlama dilleri hakkındaki Wikipedia makalesinde belirtildiği gibi, şu anda bulundukları yerden daha düşük bir seviyeye gitmek, bu sorunu daha da kötüleştirecektir :

Düşük seviyeli bir dilde yazılmış bir program, çok hızlı ve çok küçük bir bellek alanı ile çalışacak şekilde yapılabilir; yüksek seviyede bir dilde eşdeğer bir program daha ağır olacaktır. Düşük seviyeli diller basit fakat hatırlanması gereken çok sayıda teknik detay nedeniyle kullanımı zor kabul edilir .

Buna karşılık, bir üst düzey programlama dili programının şartnamenin bir bilgisayar mimarisinin yürütme semantiğini izole geliştirilmesini kolaylaştırır ...


3

Java'yı bir sözdizimi dili olarak kullanıyorsanız ve JDK kitaplıklarından kaçınırsanız, derlenmiş bir GC olmayan dil kadar hızlı olabilir. GC gerçek zamanlı sistemler için uygun değildir, ancak Java'da herhangi bir çöp bırakmayan sistemler geliştirmek mümkündür. Sonuç olarak GC asla tetiklemez.

Java dilinin ve platformunun C / C ++ 'a göre birçok avantaja sahip olduğuna inanıyoruz ve kanıtlamak için bazı ultra-düşük gecikmeli Java bileşenleri geliştirdik ve kıyasladık. Bu yazıda bunu yapma teknikleri hakkında konuşuyoruz: GC'siz Java Geliştirme .


2
Gerçek zamanlı sistemlere uygun çöp toplayıcıları vardır. JVM'nin varsayılan toplayıcısı olmayabilir, ancak bu genel olarak GC'nin gerçek zamanlı olarak uygun olmadığı anlamına gelmez. Fakat düzlük malloc/free, gerçekleşme için uygun değildir, çünkü parçalanma nedeniyle tahsis süresi sınırsızdır.
Doval,

1
Her şey için hızlı nesne havuzlarının kullanımını savunuyoruz, bu nedenle ısındıktan sonra hiçbir tahsisat yapılmıyor.
rdalmeida

2

LMAX, Yüksek Performanslı Bir Konu İçi Mesajlaşma Kütüphanesidir.

Yararlı olmak için başkasının, her iş parçacığını işe yarar hale getirecek şekilde kod yazması gerekir. Kodun Java veya C # olması muhtemel olduğu göz önüne alındığında ve onlarla iyi bir şekilde bağlantı kuran çok az dil seçeneği vardır.

Kullanıcılarınızı tek bir işletim sistemi ile sınırlamak istemediğiniz sürece C veya C ++ kullanmak iyi bir seçenek değildir, çünkü içinde tanımlanmış bir iş parçacığı modeli yoktur.

Java bugünlerde pek çok yazılım geliştirme standardıdır, bu nedenle aksi takdirde iyi bir nedeniniz yoksa, en iyi seçim olma eğilimindedir. (Romadayken, Romalılar gibi yap…)

Java'da (veya C #) Yüksek Performanslı bir yazılımın yazılması genellikle bir noktayı kanıtlamak için yapılır…


1
Yeni C ++ 11 standardı çoklu okuma destekliyor ...
Casey,

@Casey ve gerçek dünyadaki C ++ derleyicileri kaç tane kullanır? Ve bu derleyiciler ne kadara mal olur. Belki 20 yıl sonra faydalı olacak, o zamana kadar güvenemezsin.
Ian,

Yıkıcı sun.misc kullanır.Güvenli bir bit, Java'da parmağınızı C ülkesine sokmadan düşük gecikmeli kod yazamayacağınızı gösteriyor
James

3
Gcc, C ++ konularını destekler ve ücretsizdir
James

@Ian: 2 yıl sonra ve kullanılan tüm genel derleyiciler bunu destekler;). Özgür olanlar bile.
Rutix
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.