JVM(Java Virtual Machine) Nedir ?

Erkan Tekel
folksdev
Published in
5 min readSep 9, 2022

Bu yazımda çoğu Java yazılımcısının hakkında bilgi sahibi olduğu ama detaylıca bilmediği JVM (Java Virtual Machine) konusundan bahsedeceğim.

VM(Virtual Machine)

JVM kavramını anlatmadan önce VM konusuna değinmek istiyorum. Virtual Machine(Sanal Makine) fiziksel olarak var olmadığı anlamına gelir. Ama orada olduğunu hissedeceğiniz yapılardır. VM 2'ye ayrılır. İşletim tabanlı ve uygulama tabanlı.

Sanal Makine Türleri

Sistem tabanlı VM, fiziksel makine kaynaklarının farklı sanal makineler arasında paylaşılmasına izin verir. Ancak uygulama tabanlı VM, herhangi bir donanıma sahip değildir ve sanal ortamlarını oluşturmak için bazı uygulamalara veya yazılımlara ihtiyaç duyar. Uygulama tabanlı VM indirilebilir bir program değildir. Uygulamanın içinde gelen ve sadece uygulama çalıştığında çalışan, uygulama sona erdiğinde sona eren sistemlerdir.

Java Virtual Machine (JVM)

Jvm nedir? diye sorulduğunda herkesin vereceği ortak cevap Java bayt kodunu(.class dosyası) çalıştırmak ve bilgisayar donanımının anlayabileceği dile dönüştürmek diyecektir. Bu tanım doğrudur ama biraz eksiktir. JVM indirebilir bir şey değildir JRE ile çalışır. Çoğu kişinin yanıldığı bir konuda JVM statikmiş yani sadece bir kere oluştuğunu düşünür ama JVM ne kadar proje ayağa kaldırırsanız o kadar oluşur. Peki JVM’in JRE ile gelmesi bize ne katıyor? JVM o an hangi sistemde ise Java bayt kodunu bilgisayarın anlayacığı o dile çeviriyor bu da bize Java’nın her zaman söylediği “write once run everywhere” sözüne çıkartıyor.

JVM

Java Runtime Environment (JRE)

Java Runtime Environment(JRE), bir Java uygulamasının yürütülmesi için minimum gereksinimleri sağlar. Java Sanal Makinesi (JVM), java çekirdek paketleri, sınıflar ve destekleyici dosyalardan oluşur.

Java Development Kit (JDK)

Java Geliştirme Kiti (JDK), Java uygulamaları ve uygulamaları geliştirmek için kullanılan bir yazılım geliştirme ortamıdır. Java Runtime Environment(JRE), bir yorumlayıcı/yükleyici (Java), bir derleyici (javac), bir arşivleyici (jar), bir belge oluşturucu (Javadoc) ve Java geliştirmede ihtiyaç duyulan diğer araçları içerir.

JVM’nin İç Yapısı

JVM’nin İç Yapısı
JVM İç Yapısı

Yukarıdaki şemada gösterildiği gibi JVM içinde üç ana mekanizma vardır.

  1. Class Loader(Sınıf Yükleyici)
  2. Memory Area(Bellek Alanı)
  3. Execution Engine(Çalıştırma Motoru)

Class Loader

Class Loader, .class dosyasını bellek alanına yüklemekten sorumludur. Class Loader soyut bir sınıftır. Class Loader mekanizması aşağıdaki gibi üç ana adımdan oluşur.

  • Loading(Yükleme)
  • Linking(Bağlama)
  • Initialization(Başlatma)

Loading

Sınıf JVM’ye yüklendiğinde, sınıf tipinde bir nesne oluşturur ve heap alanına konur. Bu sınıf türü nesne, yalnızca sınıf JVM’ye ilk yüklendiğinde oluşturulacaktır.

Linking

Bu işlem, .class dosyasındaki verileri bellek alanına bağlama işlemidir. Class dosyasını ve derleyiciyi sağlamak için doğrulama ile başlar.

Güvenlik konuları düşünüldüğünde, kötü amaçlı yazılım gibi bazı programların .class dosyasına içerik ekleme veya değiştirme olasılığı vardır. Bu durumda, bayt kodu doğrulayıcı tarafından tanımlanacak ve “istisnayı doğrula” adı verilen bir istisna oluşturacaktır.

Doğrulama işlemi tamamlandığında bir sonraki adım hazırlıktır. Bu aşamada, tüm değişkenler varsayılan değerle başlatılır. Örnek olarak, int değişkenleri için 0, tüm nesneler için null, tüm boolean değişkenleri için false vb.

Java, programınızda herhangi bir alana özgü kelimeleri kullanmanıza izin verir. Herhangi bir isim vererek (java anahtar kelimeleri hariç) bir sınıf oluşturabilirsiniz. Ancak JVM bu kelimeleri anlayamaz. Bu nedenle, JVM bu sözcükleri bellek adresinden değiştirir. Bu üç adımın sonunda java dosyası hafıza alanına yüklenir.

Initialization

Bu, Class Loader’ın son aşamasıdır. Bu aşamada, gerçek değerler tüm statik ve örnek değişkenlere atanır. Herhangi bir aktif kullanım yapmadan önce her sınıfın başlatılması gerektiğine dair bir kural vardır. Aşağıdaki gibi altı aktif kullanım vardır.

  1. “New” anahtar kelime kullan.
  2. Statik yöntemleri çağır.
  3. Statik alanlar için değerler ata.
  4. Sınıfı başlat.
  5. Reflection API’sinde “getInstance()” kullan.
  6. Alt sınıfın somutlaştırılması.

Java’da bir sınıfı başlatmanın 4 yolu vardır.

  1. “New” Anahtar Kelimesi: Normal başlatma sürecinden geçer.
  2. Reflection API: “getInstance()” yöntemi ve normal başlatma sürecinden geçer.
  3. Klonlama Metodu: Kaynak nesneden bilgi alır.
  4. IO.Stream: Parametrede geçirilen geçici olmayan değişkenlerden veri alır.

Artık Class Loader’ın iç mekanizması hakkında bir fikrimiz var.

Memory Area

Bellek Alanı İç Yapısı

Method Area

Method Area(Yöntem alanı), sınıfla ilgili bilgileri depolar. Statik değişkenler, sınıfın kurucuları ve sınıfla ilgili diğer veriler gibi bilgiler burada saklanır.

Heap

Heap, nesne hakkındaki tüm bilgilerin depolandığı yerdir. yeni bir nesne oluşturulduğunda heap’te oluşturulacaktır. Bir nesne, o nesnenin örnek (Instance) değişkenleri hakkında bilgi sahibi olacaktır. Bir nesneye referans olmadığında, çöp toplama için uygun olacak ve sonunda heap’te yok edilecektir.

Bir sınıf bir sınıftan genişliyorsa (süper sınıfa sahipse), süper sınıfla ilgili nesneler de nesnenin içindeki heapte depolanır.

Stack

Stack, yöntem bilgilerini ve yerel değişkenleri tutacaktır. Bir metot çağrıldığında metot stack’a eklenecektir. Bir metot başka bir metotu çağırırsa, yeni metot stack’ın üstüne eklenecektir. Stack’ın en üstündeki metot, şu anda yürütülmekte olan metottur. Metot yürütmesini bitirdiğinde, yöntem yerel değişkenleriyle birlikte stack’tan kaldırılır.

PC Register

JVM’deki her iş parçacığının kendi kaydı olacaktır. Herhangi bir noktada JVM’deki bir iş parçacığı tek bir yöntem yürütüyor. İş parçacığı(thread) tarafından yürütülen yöntem yerel(native) bir yöntem değilse, bir sonraki yürütmeyle ilgili bilgiler bilgisayar kaydında(PC Register) saklanacaktır. Bilgisayar kaydı, iş parçacığı tarafından hali hazırda yürütülmekte olan yöntemin adresine sahip olacaktır. İş parçacığı yerel bir yöntem yürütüyorsa, adresin değeri tanımsız olacaktır.

Native method area

Yerel yöntem alanı(Native method area), herhangi bir yerel yöntem ve yöntem bilgisini yüklüyor veya bunlara erişiyorsanız, herhangi bir yerel yöntemi kolaylaştıracaktır. Java Sanal Makinesi talimatı için bir yorumlayıcının uygulanması, C gibi bir dilde ayarlanabilir, bu durumda yerel yöntem alanı kullanılacaktır.

Execution Engine

Yükleme ve depolama mekanizmalarının sonunda, JVM’nin son aşaması sınıf dosyasını yürütmektir. Yürütme Motorunun üç ana bileşeni vardır.

  1. Interpreter(Tercüman)
  2. JIT Compiler(JIT Derleyicisi)
  3. Garbage Collector(Çöp Toplayıcı)

Interpreter

Program çalışmaya başladığında, tercüman bayt kodunu satır satır okur. Bu işlem, bayt kodunun makine talimatlarına dönüştürülmesi gerektiğini ima eden bir tür sözlük kullanacaktır. Bu işlemin ana avantajı, tercümanın çok hızlı yüklenmesi ve hızlı yürütülmesidir.

Ancak aynı kod bloklarını (yöntemler, döngüler, vb.) tekrar tekrar çalıştırdığında, tercüman tekrar tekrar çalıştırır. Yani aynı kod tekrarı yapıldığında bunu optimize edemez.

JIT Compiler

Just In Time Compiler (JIT Derleyici), yorumlayıcının ana dezavantajının üstesinden gelmek için tanıtıldı. Bu, JIT derleyicisinin tekrar tekrar çalıştırılan kod bloklarını hatırlayabildiği anlamına gelir. Örnek olarak “Employee” adında bir sınıf var ve bu sınıfta “getEmployeeID()” metodu var. Bir program “getEmployeeID()” metodunu 1000 kez kullanırsa, tercüman tarafından her yürütüldüğünde yeniden çağırılacaktı. Ancak JIT derleyicisi bu tekrarlanan kod bölümlerini tanımlayabilir ve bunlar önbellekte yerel kodlar olarak depolanır. Depolandığından, bir dahaki sefere JIT derleyicisi önbellekte depolanan yerel kodu kullanır.

Umarım yararlı bir yazı olmuştur ve JVM mimarisini net bir şekilde anlamışsınızdır.

Reference

https://www.geeksforgeeks.org/jvm-works-jvm-architecture/

https://www.javatpoint.com/jvm-java-virtual-machine

--

--