Java Virtual Machine

**JVM** — Java ekotizimining yadrosi boʻlib, Javaga asoslangan dasturiy taʼminotlarga **"bir marta yozing, istalgan joyda ishga tushiring"** yondashuviga amal qilish imkonini beradi. Java kodini bitta mashinada yozishingiz va uni JVM yordamida istalgan boshqa mashinada ishga tushirishingiz mumkin. JVM dastlab faqat Javani qoʻllab-quvvatlash uchun ishlab chiqilgan edi. Biroq, vaqt oʻtishi bilan Java platformasida Scala, Kotlin va Groovy kabi koʻplab boshqa tillarni ham ishga tushirish imkoni tugʻildi. Bu tillarning barchasi birgalikda JVM tillari deb nomlanadi.

## Java virtual mashinasi nima?
C va C++ kabi dasturlash tillarida kod dastlab platformaga xos mashina kodiga kompilyatsiya qilinadi. Bu tillar kompilyatsiya qilingan yoki kompilyater tillar deb ataladi. Boshqa tomondan, JavaScript va Python kabi tillarda kompyuter koʻrsatmalarni kompilyatsiya qilmasdan toʻgʻridan-toʻgʻri bajaradi. Bu tillar izohli yoki interpreter tillar deb ataladi. Java ikkala texnikaning kombinatsiyasidan foydalanadi. Java kodi klass faylini yaratish uchun avval maxsus java bayt kodga kompilyatsiya qilinadi. Keyinchalik bu klass fayli asosiy platforma uchun Java virtual mashinasi tomonidan ishga tushiriladi. Xuddi shu klass fayl har qanday platforma va operatsion tizimda ishlaydigan JVM ning istalgan versiyasida ishga tushirilishi mumkin. Virtual mashinalarga oʻxshab, JVM host mashinasida yaʼni JVM oʻrnatilgan mashinada oʻzi uchun alohida joy yaratadi. Bu maydon platforma yoki mashinaning operatsion tizimidan qatʼi nazar, Java dasturlarini ishga tushirish uchun ishlatilishi mumkin.

## Java virtual mashinasi arxitekturasi

JVM uchta alohida komponentdan iborat:
* klasslarni yuklovchi qism yani klassloaderlar(ingliz tilida classloaders deb ataladi)
* amalga oshirish jarayonidagi maʼlumotlarni saqlovchi xotira qism (ingliz tilida runtime memory areas deyiladi)
* amallarni bajaruvchi qism(ingliz tilida execution engine deyiladi)

### Klasslarni xotiraga yuklovchilar (classloaders)
Klassloaderlarning asosiy vazifa programmadagi klasslarni java virtual mashinasi tomonidan ishlatilinishi kerak boʻlgan vaqtda xotiraga yuklashdan iborat. Javada bir nechta klass turlari mavjud. Masalan java dasturlash tilida oldindan yaratilgan klasslar yoki tashqi kutubxonalardan chaqirilgan klasslar va dasturchi tomonidan yaratilgan klasslar kabi klass turlari mavjud. Shu jihatdan JVM da 3 xil klassloaderlar mavjud. Bular quyidagicha:
* Bootstrap klassloaderlar
* Extension klassloaderlar
* Sistema klassloaderlari
**Bootstrap klassloaderlar** — bu klassloaderlar java dasturlash tilida oldindan yaratilgan yoki boʻlmasam kompyuter xotirasida JAVA/JRE/LIB yoʻlida joylashgan klass fayllarni yuklash uchun ishlatilinadi. Bu klassloader barcha klasslaoderlarning otasi hisoblanadi.

**Extension klassloader** — bu klassloader tashqaridan yuklangan ekstentionlar yaʼni kutubxonalardagi klasslarni yuklaydi. Bu klassloader JAVA/JRE/LIB/EXT yoʻlidagi klasslarni xotiraga yuklaydi.

**Application klassloader(sistema klassloaderi**) — bu klassloader dasturchi tomonidan yaratilgan yoki classpath yoʻlidagi klasslarni yuklash uchun ishlatilinadi.


### Klasslarni yuklovchilarning uchta asosiy vazifasi, klassning yuklanish bosqichlari
Klassloaderlarning asosiy uchta vazifasi bor, bular:
* Klasslarni yuklash(Loading)
* Bogʻlash(Linking)
* Initializatsiya(Ishga tushirish)

**Birinchi qadam**da classloader „.class“ kengaytmali faylni oʻqiydi va unga mos ikkilik maʼlumot ishlab chiqib uni method area deb nomlangan xotiraga saqlaydi. Har bir klass fayl uchun JVM quyidagi maʼlumotlarni xotiraga saqlaydi:
* Yuklangan klass faylning toʻliq nomi va uning ota klassi nomi
* Klass faylning turi, u klassmi, interfeysmi yoki enum turidagi faylmi, shu haqidagi maʼlumot
* Klass faylda joylashgan oʻzgaruvchilar, metodlar va shunga oʻxshash maʼlumot

Klass fayl yuklangandan soʻng, JVM heap memory deb ataluvchi xotirada Class tipidagi bu klass haqidagi maʼlumotlarni koʻrsatib turish uchun obyekt yaratadi. Bu klass obyekti dasturchi tomonidan klass haqidagi maʼlumotar, masalan, nomi, metodlari va boshqalarni olish uchun ishlatilinadi.

**Ikkinchi qadam** bogʻlash deb nomlanadi va bunda .class faylni yaroqli kompilyator tomonidan kompilyatsiya qilinganligi tekshiriladi. Agar qandaydir xatolik boʻlsa verifikatsiyada xatolik deb ataluvchi verificationexception xatoligini tashlaydi. Bundan tashqari klass fayldagi statik oʻzgaruvchilarni dastlabki(default) qiymatlari beriladi. Shu bilan birga, simbollar orqali bogʻlanishlarni bevosita bogʻlanishlarga almashtiriladi. Masalan, klass nomining oʻrniga xotirada joylashgan nomi ishlatilinadi.

**Uchinchi qadam**da esa ishga tushirish jarayoni boʻladi yaʼni kodda berilgan statik oʻzgaruvchilarni qiymati belgilanadi va klass ichidagi statik blok ichida yozilgan kod ishga tushiriladi. 

### Klasslarning yuklanish mexanizmi

Javada klass maxsus „Delegation-Hierarchy“ prinsipiga amal qilgan holda yuklanadi. Qachonki, jvm dastur ishlash jarayonida biron bir klassga duch kelsa, avvalo, xotiradan bu klass yuklangan yoki yoʻqligini tekshiradi. Agar yuklangan boʻlsa foydalanadi, aks holda, klassloaderlarga murojaat qiladi, soʻrov birinchi navbatda application klassloaderga keladi, bu klassloader soʻrovni extension klassloaderga joʻnatadi, extension klassloader esa bootstrap klassloaderga yuboradi. Bootstrap klassloader oʻzi mas’ul boʻlgan papkani qaraydi, agar klassni topsa, uni yuqorida koʻrsatilgan tartibda yuklaydi, aks holda, soʻrov yana extension klassloaderga keladi, u ham oʻzi mas’ul boʻlgan papkalar orasidan klass faylni qidiradi, agar fayl topilsa yuklanadi, aks holda, application klassloaderga soʻrov joʻnatiladi, agar bu klassloader ham klass faylni topa olmasa, JVM tomonidan classNotFoundException deb ataluvchi xatolik qaytariladi.

## Amallarni bajaruvchi komponenta(Execution engine)
Amallarni bajaruvchi komponenta ham oʻz navbatida uchta qismga boʻlinadi, bular:
* Interpretator
* JIT (Just in time — inglizcha, ayni vaqtda) kompilyator
* Garbage collector (xotira tozalovchi)
**Interpretator** — xotiraga yuklangan klassdagi bayt kodlarni qatorma-qator oʻqiydi va kodni ishga tushiradi. Buni asosiy kamchiligi, kodlarni har safar qayta va qayta kompilyatsiya qilinishidadir.

**JIT kompilyator** — buning asosiy vazifasi jvmda ish jarayonini tezlashtirish va optimizatsiya qilish hisoblanadi. JIT ning ustunlik beruvchi tarafi bu agar bayt kod oldin kompilyatsiya qilingan boʻlsa, qaytadan qilmasdan oʻsha kompilyatsiya qilingan kodni ishga tushiradi va bu amallar bajarilish jarayoni sezilarli darajada tezlashishiga sabab boʻladi.

**Garbage collector** — bu xotirani optimizatsiya qilishga yordam beradi, yaʼni xotiradagi qiymat yoʻq boʻlin qolgan(„null“ boʻlgan) yoki boshqa obyektlar bilan bogʻlanishi yoʻqolgan obyektlarni heap xotirasidan tozalab turadi. Bu esa xotira toʻlib qolishini oldini oladi. Baʼzi C, Fortan, Pascal kabi tillarda bu jarayon dasturchilar tomonidan qoʻlda amalga oshiriladi. Shuning uchun, avtomatik xotira tozalanishi javaning boshqa tillardan ustunlik qiladigan muhim jihatlaridan biridir.

## Manbalar

## Havolalar
* JVM ishlash mexanizmi haqida
* Klassloaderlar haqida maʼlumot
* JIT kompilyator uchun manba
* Garbage collector uchun manba
* JVM qanday ishlashi haqida sodda tilda yozilgan manba
* JVM ishlashi haqida ingliz tilida foydali maʼlumot 
* Klassloaderlarni oʻrganish uchun Oracle kompaniyasi dokumentatsiyasi