İşletim sistemleri bellek alanlarında G / Ç işlemleri gerçekleştirir. Bu bellek alanları, işletim sistemi ile ilgili olarak, bitişik bayt dizileridir. O zaman sadece bayt arabelleklerinin G / Ç işlemlerine katılmaya uygun olması şaşırtıcı değildir. Ayrıca, işletim sisteminin verileri aktarmak için işlemin adres alanına, bu durumda JVM işlemine doğrudan erişeceğini unutmayın. Bu, G / Ç işlemlerinin hedefi olan bellek alanlarının bitişik bayt dizileri olması gerektiği anlamına gelir. JVM'de, bir bayt dizisi bitişik olarak bellekte saklanamayabilir veya Çöp Toplayıcı herhangi bir zamanda taşıyabilir. Diziler Java'daki nesnelerdir ve verilerin bu nesnenin içinde depolanma biçimi bir JVM uygulamasından diğerine değişebilir.
Bu nedenle, doğrudan bir tampon kavramı getirildi. Doğrudan tamponlar kanallarla ve yerel G / Ç rutinleriyle etkileşim için tasarlanmıştır. Bayt öğelerini, işletim sistemine doğrudan bellek alanını boşaltmasını veya doldurmasını söylemek için yerel kodu kullanarak kanalın doğrudan veya ham erişim için kullanabileceği bir bellek alanında saklamak için en iyi çabayı gösterirler.
Doğrudan bayt arabellekleri genellikle G / Ç işlemleri için en iyi seçimdir. Tasarım gereği, JVM'nin kullanabileceği en verimli I / O mekanizmasını desteklerler. Doğrudan olmayan bayt arabellekleri kanallara geçirilebilir, ancak bunu yapmak performans cezasına neden olabilir. Doğrudan olmayan bir arabelleğin yerel bir G / Ç işleminin hedefi olması genellikle mümkün değildir. Yazmak için bir kanala doğrudan olmayan bir ByteBuffer nesnesi iletirseniz, kanal her çağrıda dolaylı olarak aşağıdakileri yapabilir:
- Geçici bir doğrudan ByteBuffer nesnesi oluşturun.
- Doğrudan olmayan arabelleğin içeriğini geçici arabelleğe kopyalayın.
- Geçici arabelleği kullanarak düşük seviye G / Ç işlemini gerçekleştirin.
- Geçici arabellek nesnesi kapsam dışına çıkar ve sonunda çöp toplanır.
Bu, potansiyel olarak her G / Ç üzerinde tam olarak kaçınmak istediğimiz şeyler olan tampon kopyalamaya ve nesne karmaşasına neden olabilir. Ancak, uygulamaya bağlı olarak, işler bu kadar kötü olmayabilir. Çalışma zamanı, doğrudan arabellekleri önbelleğe alır ve yeniden kullanır veya verimi artırmak için başka akıllı numaralar gerçekleştirir. Tek seferlik kullanım için sadece bir tampon oluşturuyorsanız, fark önemli değildir. Öte yandan, ara belleği yüksek performanslı bir senaryoda tekrar tekrar kullanacaksanız, doğrudan arabellekleri ayırıp yeniden kullanmanız daha iyi olur.
Doğrudan arabellekler I / O için en uygunudur, ancak doğrudan bayt arabelleklerinden daha pahalı olabilirler. Doğrudan arabellekler tarafından kullanılan bellek, standart JVM yığınını atlayarak yerel, işletim sistemine özgü koda çağrılarak tahsis edilir. Doğrudan arabelleklerin ayarlanması ve yırtılması, ana bilgisayar işletim sistemine ve JVM uygulamasına bağlı olarak yığınta yerleşik arabelleklerden önemli ölçüde daha pahalı olabilir. Doğrudan arabelleklerin bellek depolama alanları, standart JVM yığınının dışında oldukları için çöp toplamaya tabi değildir.
Doğrudan ve doğrudan olmayan arabellekleri kullanma performans sıralamaları JVM, işletim sistemi ve kod tasarımına göre büyük farklılıklar gösterebilir. Yığın dışında bellek ayırarak, uygulamanızı JVM'nin farkında olmadığı ek güçlere maruz bırakabilirsiniz. Ek hareketli parçaları oyuna dahil ederken, istediğiniz efekti elde ettiğinizden emin olun. Eski yazılım maxim'i öneriyorum: önce çalışmasını sağlayın, sonra hızlı yapın. Optimizasyon konusunda çok endişelenmeyin; önce doğruluk üzerine konsantre olun. JVM uygulaması, çok fazla gereksiz çaba harcamadan size ihtiyacınız olan performansı verecek tampon önbellekleme veya diğer optimizasyonları gerçekleştirebilir.