Çook uzun zamandır yazmadığım siteme, aldığım çok sağlam bir destek ve moral neticesinde şu an okuyacağınız JVM Mimarisini anlatacağım bu yazıyla geri dönüyorum 🙂
JVM mimarisine girmeden önce bir java kodunun ve hatta herhangi bir programlama dili ile yazılmış bir kodun derlenip çalıştırılma sürecindeki bazı temel kavramlar üzerinden geçmekte fayda var.
Ön Bilgiler
- Machine Code (Machine Language): Makine kodu ya da makine dili, direkt olarak bir mikroişlemci/mikrodenetleyici üzerinde işletilebilecek komutlardan oluşan en alt seviyedeki programlama dilidir. İşlemci mimarisine/donanımına göre komut seti (instruction set) değişebilmektedir. Donanım diline uzak, insan diline yakın olan yüksek seviyeli diller ile yazılmış kodlar, hangi işlemci üzerinde çalışacak ise öncelikle bu işlemcinin komut setine uygun olarak derlenerek makine kodu oluşturulmak zorundadır.
- Bytecode : Bir yorumlayıcı tarafından işletilebilir/çalıştırılabilir ve aynı zamanda makine diline derlenebilir durumdaki ikili (binary) dosyadır. Bytecode aynı zamanda “taşınabilir kod” olarak da adlandırılır. Bytecode a derlenen dillere Erlang, .NET Framework dilleri, JVM dilleri (Java, Clojure, Scala, Kotlin), Python örnek olarak verilebilir.
- Java Bytecode : Bir önceki bytecode tanımına istinaden; bir java kodunun java compiler (javac) ile derlenmesi sonrası oluşan, JVM tarafından yorumlanmaya/işletilmeye hazır hale getirilmiş ikili (binary) dosyadır. Javanın “write once, run anywhere” sloganının temelinde java bytecode ve JVM birlikte yatmaktadır.
- JRE (Java Runtime Environment) : Bir java programının çalışabilmesi için gerekli olan JVM ve JVM için gerekli dosyaları içeren ortamdır.
- JDK (Java Development Kit) : Bir java programını geliştirmek için gerekli olan araçları (java compiler, debugger, javadoc gibi) ve JRE yi içeren settir.
- JVM (Java Virtual Machine) : Java bytecode unu yorumlayarak işletecek olan java sanal makinesidir.

Derleme/Çalıştırma
Java kodunu javac ile derlediğimizde bytecode un oluştuğunu söylemiştik. Bu dosyalar .class uzantılı dosyalardır.
Örneğin aşağıdaki gibi System.out a “JVM Mimarisi” yazan bir Program.java isimli bir java kodumuz olsun.

Program.java yı derlemek için javac aracını kullanıyoruz. Derledikten sonra Program.class adında bytecode dosyası oluşuyor.

Son olarak java ile programımızı çalıştırıyoruz.

İşte tam burada, yani java programını çalıştırdığımızda yeni bir JVM instance yaratılıyor ve bytecode işletilmeye başlanıyor.
Şimdi bu işletim sürecini ve JVM mimarisini detaylıca inceleyebiliriz.
JVM Mimarisi
JVM temel olarak Class Loader, Runtime Data Area ve Execution Engine olmak üzere 3 parçadan oluşmaktadır.

Class Loader
Class loader sisteminin görevi çalışma sırasında gerektiği zaman class dosyalarını yüklemek (loading), bağlamak (linking) ve başlatmak(initialize) tır.
Loading: Bu sistem Bootstrap class Loader, Extension class loader ve Application class loader dan oluşmaktadır.
- Bootstrap class Loader: JAVA_HOME/jre/lib altındaki Java nın temel class dosyalarını yükleme işini yapan class loader dır. Örn: rt.jar kütüphanesi (java.*, javax.* vs temel paketler)
- Extension class loader: JAVA_HOME/jre/lib/ext altındaki ek class dosyalarını yükleme işini yapan class loader dır.
- Application class loader: Java uygulamamız çalışırken gereken uygulama seviyesindeki class dosyalarını yüklemekten sorumlu class loader dır.
Class loader lar arasında bir class yükleme isteği geldiğinde işletilen Delegation-Hierarchy principle algoritması vardır. Bu algoritmaya göre istek bootstrap class loader a kadar gider ve burada class bulunamazsa extension class loader da ve son olarak application class loader da aranır. Eğer bulunamaz ise hemen hemen her javacının karşılaştığı java.lang.ClassNotFoundException runtime exception ı fırlatılır.
Linking:
- Verification : class dosyasının doğrulaması yapılır (dosya formatı, compiler versiyonu gibi kontroller).
- Preparation : class için gerekli referanslara bellekten yer ayrılır ve varsayılan değerler atanır.
- Resolution : class içindeki varsa sembolik referanslar method area içindeki gerçek referanslar ile yer değiştirilir.
Initialization:
Statik değişkenlerin kod içindeki değerlerinin verildiği ve statik kod bloklarının işletildiği aşamadır.
Runtime Data Areas
Method area: Yüklenmiş olan bütün class bilgilerinin, class ilişkilerinin, metot ve statik değişkenlerin bilgilerinin tutulduğu yerdir. Threadler için paylaşılan bir alandır.
Heap area: Bütün yaratılan nesnelerin tutulduğu yerdir. Heap de threadler için paylaşılan bir alandır.
Stack area: Her bir thread için yaratılan stack yapılarının tutulduğu alandır. Bir thread in stack i içerisinde yerel metot değişkenlerinin de bulunduğu, her metod çağrımı için birer tane stack frame i bulunur. Metod işletilip sonuç döneceği zaman frame silinir ve stack içindeki bir önceki frame e geçilir. Thread sonlandığında ilgili stack de silinir.
PC(Program Counter) Registers: Bir threadin o andaki işletilen komutunun bilgisini tutar, işletildikçe güncellenir. Her bir thread için ayrı bir pc register ı vardır.
Native method stacks: Her bir thread için ayrı tutulan ve native stack bilgilerinin bulunduğu kısımdır.
Execution Engine
Bu kısımda runtime data area da bilgileri bulunan bytecode adım adım yorumlanarak işletilir.
Interpreter: Bytecode u parça parça okur, çevirir ve işletir.
JIT (Just in Time) Compiler: Bytecode u makine diline derler. Bunu yaparken aynı zamanda interpreter verimini artırmak için, tekrar eden bytecode parçalarını (örneğin aynı metodun tekrar çağırılması) daha önceki derlediği makine kodunu vererek, profil tutarak vs. optimizasyon ve performans artırımını sağlar.
Garbage Collector: :Referansını kaybetmiş, artık kullanılmayan nesnelerin temizlenmesini sağlar.
Java Native Interface (JNI): Execution engine çalışması sırasında ihtiyaç duyduğu native metotları çağırır. (İşletim sistemi/donanım özelindeki fonksiyonlar)
Native Method Libraries: JNI ın kullanacağı native metot kütüphaneleridir.
Yararlanılan Kaynaklar:
- https://www.geeksforgeeks.org/jvm-works-jvm-architecture/
- https://www.javacodegeeks.com/2018/04/jvm-architecture-jvm-class-loader-and-runtime-data-areas.html
- https://dzone.com/articles/jvm-architecture-explained


