JavaRush /Java блогу /Random-KY /Капоттун астында Java тиркемелерин түзүү жана аткаруу
Павел Голов
Деңгээл
Москва

Капоттун астында Java тиркемелерин түзүү жана аткаруу

Группада жарыяланган

Мазмуну:

  1. Киришүү
  2. Байтcodeго компиляциялоо
  3. Программаны түзүү жана аткаруунун мисалы
  4. Виртуалдык машинада программаны аткаруу
  5. Just-in-time (JIT) компиляциясы
  6. Корутунду
Капоттун астында Java тиркемелерин түзүү жана аткаруу - 1

1. Киришүү

Баарына салам! Бүгүн мен Java жазуу түрүндөгү тиркемесин иштеткенден кийин JVM (Java Virtual Machine) капотунун астында эмне болору тууралуу бorм менен бөлүшкүм келет. Бүгүнкү күндө JVMдин ички түзүлүштөрү жөнүндө ойлонбоого, Java codeун түзүүгө жана аткарууга жардам берген модалуу өнүктүрүү чөйрөлөрү бар, бул жаңы иштеп чыгуучулардын бул маанилүү аспектилерди өткөрүп жиберишине алып келиши мүмкүн. Ошол эле учурда бул темага байланыштуу суроолор интервью учурунда көп берилет, ошондуктан мен макала жазууну чечтим.

2. Байтcodeго компиляция

Капоттун астында Java тиркемелерин түзүү жана аткаруу - 2
Келгиле, теориядан баштайлы. Кандайдыр бир тиркемени жазганда кеңейтүүсү бар файлды түзүп .java, ага Java программалоо тorнде codeду жайгаштырабыз. Адам окуй турган codeун камтыган мындай файл баштапкы code файлы деп аталат . Баштапкы code файлы даяр болгондон кийин, аны аткарышыңыз керек! Бирок этапта ал адамдарга гана түшүнүктүү маалыматтарды камтыйт. Java – көп платформалуу программалоо тor. Бул Java тorнде жазылган программаларды Java иштөө убактысынын атайын системасы орнотулган каалаган платформада аткарууга болот дегенди билдирет. Бул система Java Virtual Machine (JVM) деп аталат. Программаны баштапкы codeдон JVM түшүнө турган codeго которуу үчүн, аны компиляциялашыңыз керек. JVM түшүнгөн code byte code деп аталат жана виртуалдык машина кийин аткара турган көрсөтмөлөрдүн жыйындысын камтыйт. Булак codeун bytecodeго компиляциялоо үчүн javacJDK (Java Development Kit) компилятору бар. Киргизүү катары компилятор .javaпрограмманын баштапкы codeун камтыган кеңейтүүсү бар файлды кабыл алат, ал эми чыгаруу катары .classвиртуалдык машина тарабынан программанын аткарылышы үчүн зарыл болгон byte-codeду камтыган кеңейтүүсү бар файлды чыгарат. Программа bytecodeго компиляциялангандан кийин, аны виртуалдык машинанын жардамы менен аткарууга болот.

3. Программаны түзүү жана аткаруунун мисалы

Бизде файлда камтылган Calculator.java, 2 сандык буйрук сабынын аргументтерин алып, аларды кошуунун натыйжасын басып чыгарган жөнөкөй программа бар дейли:
class Calculator {
    public static void main(String[] args){
        int a = Integer.valueOf(args[0]);
        int b = Integer.valueOf(args[1]);

        System.out.println(a + b);
    }
}
Бул программаны bytecodeго компиляциялоо үчүн, биз javacбуйрук сабында компиляторду колдонобуз:
javac Calculator.java
Компиляциядан кийин биз bytecodeу бар файлды чыгарабыз Calculator.class, аны компүтерде орнотулган java машинасы аркылуу буйрук сабындагы java буйругун колдонуп аткара алабыз:
java Calculator 1 2
Белгилей кетсек, файлдын аталышынан кийин 2 командалык сап аргументи көрсөтүлгөн - 1 жана 2 сандар. Программаны аткаргандан кийин командалык сапта 3 саны көрсөтүлөт.Жогорудагы мисалда бизде өз алдынча жашаган жөнөкөй класс болгон. . Бирок класс кандайдыр бир пакетте болсочы? Төмөнкү кырдаалды окшоштуралы: каталогдорду түзүп src/ru/javarush, классыбызды ошол жерге жайгаштырыңыз. Эми мындай көрүнөт (файлдын башына пакеттин атын коштук):
package ru.javarush;

class Calculator {
    public static void main(String[] args){
        int a = Integer.valueOf(args[0]);
        int b = Integer.valueOf(args[1]);

        System.out.println(a + b);
    }
}
Мындай классты төмөнкү команда менен түзөлү:
javac -d bin src/ru/javarush/Calculator.java
Бул мисалда биз компиляцияланган файлдарды каталогго окшош структурасы бар -d binкаталогго салган кошумча компилятордун опциясын колдондук , бирок каталог алдын ала түзүлүшү керек. Бул ыкма баштапкы code файлдарын byte-code файлдары менен чаташтырбоо үчүн колдонулат. Түзүлгөн программаны иштетүүдөн мурун, түшүнүктү түшүндүрүп берүү керек . виртуалдык машина пакеттерди жана компиляцияланган класстарды издей турган жол. Башкача айтканда, ушундай жол менен биз виртуалдык машинага файл тутумундагы кайсы каталогдор Java пакетинин иерархиясынын тамыры экенин айтабыз. желектин жардамы менен программаны баштаганда көрсөтүлүшү мүмкүн . Биз программаны буйрук менен ишке киргизебиз: binsrcbinclasspathClasspathClasspath-classpath
java -classpath ./bin ru.javarush.Calculator 1 2
Бул мисалда биз класстын толук атын, анын ичинде ал жайгашкан пакеттин атын талап кылдык. Акыркы файл дарагы төмөнкүдөй көрүнөт:
├── src
│     └── ru
│          └── javarush
│                  └── Calculator.java
└── bin
      └── ru
           └── javarush
                   └── Calculator.class

4. Виртуалдык машина менен программанын аткарылышы

Ошентип, биз жазылган программаны ишке киргиздик. Бирок компиляцияланган программа виртуалдык машина тарабынан ишке киргизилгенде эмне болот? Биринчиден, компиляция жана codeду чечмелөө түшүнүктөрү эмнени билдирерин аныктап көрөлү. Компиляция – бул жогорку деңгээлдеги баштапкы тилде жазылган программаны машина codeуна окшош төмөнкү деңгээлдеги тилдеги эквиваленттүү программага которуу. Интерпретация – оператор боюнча (команда боюнча, сап боюнча) талдоо, иштеп чыгуу жана баштапкы программаны же суроо-талапты дароо аткаруу (компиляциядан айырмаланып, программа аны аткарбастан которулат). Java тorнде компилятор ( javac) да, интерпретатор да бар, ал виртуалдык машина byte codeду сап боюнча машина codeуна айландыруучу жана аны дароо аткарат. Ошентип, биз компиляцияланган программаны иштеткенде, виртуалдык машина аны интерпретациялай баштайт, башкача айтканда, byte-codeду машина codeуна сапка которуу, ошондой эле анын аткарылышы. Тилекке каршы, byte-codeдун таза интерпретациясы бир кыйла узак процесс жана атаандаштарына салыштырмалуу Javaны жайлатат. Буга жол бербөө үчүн виртуалдык машина byte-codeду чечмелөөнү тездетүү механизми киргизилген. Бул механизм Just-in-time Compilation (JITC) деп аталат.

5. Just-in-time (JIT) компиляциясы

Жөнөкөй сөз менен айтканда, Just-In-Time компиляциясынын механизми мындай: эгерде программада codeдун көп жолу аткарылган бөлүктөрү бар болсо, анда келечекте алардын аткарылышын тездетүү үчүн аларды машина codeуна бир жолу компиляциялоого болот. Программанын мындай бөлүгүн машиналык codeго компиляциялагандан кийин, программанын бул бөлүгүнө ар бир кийинки чакырууда виртуалдык машина компиляцияланган машина codeун интерпретациялоонун ордуна дароо аткарат, бул табигый түрдө программанын аткарылышын тездетет. Программаны тездетүү эстутум керектөөнү көбөйтүү жолу менен (биз компиляцияланган машина codeун бир жерде сакташыбыз керек!) жана программаны аткаруу учурунда компиляцияга кеткен убакытты көбөйтүү менен жетишилет. JIT компиляциясы - бул өтө татаал механизм, андыктан жогору жагын карап көрөлү. JIT компиляциясынын 4 деңгээли бар byte codeду машина codeуна. Компиляциянын деңгээли канчалык жогору болсо, ал ошончолук татаал, бирок ошол эле учурда мындай бөлүмдүн аткарылышы төмөнкү деңгээли бар бөлүмгө караганда тезирээк болот. JIT - Компилятор программанын ар бир фрагменти үчүн кандай компиляция деңгээлин коюуну чечет, ал фрагмент канчалык көп аткарылганына жараша. Капчыктын астында JVM 2 JIT компиляторун колдонот - C1 жана C2. C1 компилятору кардар компилятору деп да аталат жана codeду 3-деңгээлге чейин гана түзүүгө жөндөмдүү. C2 компилятору 4-, эң татаал жана эң тез компиляция деңгээлине жооп берет.
Капоттун астында Java тиркемелерин түзүү жана аткаруу - 3
Жогоруда айтылгандардан биз жөнөкөй кардар тиркемелери үчүн C1 компиляторун колдонуу пайдалуураак деген тыянак чыгарууга болот, анткени бул учурда биз үчүн тиркеме канчалык тез башталаары маанилүү. Сервер тараптагы, узак мөөнөттүү тиркемелерди баштоо үчүн көбүрөөк убакыт талап кылынышы мүмкүн, бирок келечекте алар иштеп, өз функцияларын тез аткарышы керек - бул жерде C2 компилятору бизге ылайыктуу. -clientJVMдин x32 versionсында Java программасын иштетип жатканда, жана желекчелери аркылуу кайсы режимди колдонгубуз келгенин кол менен белгилей алабыз -server. Бул желек көрсөтүлгөндө, -clientJVM татаал byte-code оптималдаштырууну аткарbyte, бул колдонмону баштоо убактысын тездетет жана сарпталган эстутумдун көлөмүн азайтат. Желекти көрсөтүүдө, -serverbyte-codeдун татаал оптималдашуусунан улам, колдонмону баштоо үчүн көбүрөөк убакыт талап кылынат жана машина codeун сактоо үчүн көбүрөөк эстутумду колдонот, бирок программа келечекте тезирээк иштейт. JVMдин x64 versionсында желек -clientэтибарга алынbyte жана колдонмо serverинин конфигурациясы демейки боюнча колдонулат.

6. Корутунду

Бул менин Java тиркемесин компиляциялоо жана аткаруу боюнча кыскача баяндамамды аяктайт. Негизги пункттар:
  1. Javac компилятору программанын баштапкы codeун Java виртуалдык машинасы орнотулган каалаган платформада аткарыла турган bytecodeго айлантат;
  2. Компиляциядан кийин JVM пайда болгон byte codeду чечмелейт;
  3. Java тиркемелерин тездетүү үчүн JVM программанын эң көп аткарылуучу бөлүмдөрүн машина codeуна айландырган жана аларды эс тутумда сактаган Just-In-Time компиляция механизмин колдонот.
Бул макала сизге биздин сүйүктүү программалоо тorбиз кантип иштээрин тереңирээк түшүнүүгө жардам берди деп үмүттөнөм. Окуу үчүн рахмат, сын кабыл алынат!
Комментарийлер
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION