2015-09-11 49 views
5

JVM tarafından işlenen staticfinal alanlarının nasıl olduğunu merak ediyorum. Benzer bir soru gördüm here ama aradığım şey değil. en tür örneği ele alalım:Son statik olmayan alanlar ve JVM optimizasyonu

public class TestClassX { 
    public final int CODE_A = 132; 
    public final int CODE_B = 948; 
    public final int CODE_C = 288; 
    // some other code 
} 

public class TestClassY { 
    public static final int CODE_A = 132; 
    public static final int CODE_B = 948; 
    public static final int CODE_C = 288; 
    // some other code 
} 

TestClassX yılında alanları, bunlar final ve değiştirilemez, TestClassX sınıfın tüm örnekleri aynı değerlere sahip olarak. Tabii ki TestClassX.CODE_A yazamıyorum ama bu değerlerin aslında tüm örnekler için yaygın olduğunu söyleyebilirim - eminim ki, her örnekte 132 değerine sahip CODE_A alanı var.

TestClassYTestClassY.CODE_A sözdizimini kullanabilirim, ancak ilk bakışta "Oh, bu değerler tüm örneklerde yaygındır" gören bir geliştirici için daha kolaydır.

Benim asıl soru: Ben JVM, TestClassX durumunda, final alanlar yeni bir örneği her oluşturulduğunda için herhangi bir ekstra bellek kullanmaz tahmin. Yapar? JVM bu durumda herhangi bir optimizasyon yapar mı ve ne tür bir optimizasyon?

Ekstra soru 1) Ayrıca şüphelerimin sebebi olan burada çok önemli bir şeyi kaçırdığımı da biliyorum. Bu da ne?

Ekstra soru 2) Btw. JVM optimizasyonundan sonra Java kaynak kodumun nasıl göründüğüne nasıl göz atabilirim (böylece gelecekte de kullanabilirim;))? Herhangi bir IDE böyle bir işlevselliği destekliyor mu? Örneğin IntelliJ? JVM'nin TestClassX ve TestClassY numaramı nasıl ele aldığını görmek isterim.

+0

ilgili - https://groups.google.com/forum/#!topic/java-lang-fans/AyS3UqX4lj4 – ZhongYu

+0

2) JVM optimizasyonlar değiller - Javac hep :) sürekli örnek değişkenler, muhtemelen bir hata inlines kendisini, Java kaynağı olarak ifade edilmeye teşvik edecek şekilde yapılmadı. Derleyiciler, kodun * yaptıklarının dahili bir temsilini optimize ederler.source-> source optimizers genellikle, her kullanıldığında (örneğin javascript) derlenmesi gereken diller için vardır. Buradaki asıl amacınız, Java bayt koduna veya belirli bir CPU için JIT-derlemesinden kaynaklanan asm'a bakılarak ele alınmalıdır. (Ya da gcj gibi Java uygulamalarını geleneksel olarak derleyen bir zaman.) –

cevap

6
  • Örneklerde statik olmayan alanlar daima mevcuttur. Hafızayı kaydetmezler.
  • Genel olarak JVM statik olmayan alanları optimize etmez. Final olsalar bile, yansımayı kullanarak ya da serileştirme sırasında hala farklı değerlere ayarlanabilirler.
  • JVM'ye bu tür alanlara erişimi en iyi duruma getirme, yani sabit olarak işleme ve alan yüklerini ortadan kaldırması için söyleyen bir VM öğesinin -XX:+TrustFinalNonStaticFields (kapalı varsayılan) seçeneği vardır.
  • JIT derlenmiş kodu dökmek için bir -XX:+PrintAssembly VM seçeneği vardır.
+0

Yansıma ve desantizasyondan bahsettiğiniz için teşekkürler . Ve TrustFinalNonStaticFields seçeneği için - Bilmiyordum! ... ^ –

1

Sorunuzun ilk kısmı için, belki this answer size yardımcı olabilir.

İkinci bölüm için, kodunuzu çalıştırdığınızda/derlerken -XX:+PrintOptoAssembly bayrağını ekleyerek (this answer numaralı belgede belirtildiği gibi) oluşturulan derlemeyi görebilirsiniz.

Ayrıca, size verilen derleme kodunun jvm tarafından oluşturulan gerçek kod olmadığını, ancak gerçek mimarinizin altında çalıştırılması gereken kodu eklemeliyim.

Bu yardımcı olur umarız!

+0

Bir yorum olarak göndermediğim için üzgünüm, ancak bunu yapmak için yeterli saygınlığım yok ... –