1 / 62

Java Virtual Machine

Java Virtual Machine. Specyfikacja - najważniejsze zagadnienia. XI.2003 Mirosław Szymański Wydział Matematyki, Informatyki i Mechaniki Uniwersytetu Warszawskiego. Spis treści. Wstęp Struktura JVM Instrukcje wirtualnej maszyny Pliki class Ładowanie, łączenie, inicjalizacja

bina
Télécharger la présentation

Java Virtual Machine

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Java Virtual Machine Specyfikacja - najważniejsze zagadnienia XI.2003 Mirosław Szymański Wydział Matematyki, Informatyki i Mechaniki Uniwersytetu Warszawskiego

  2. Spis treści • Wstęp • Struktura JVM • Instrukcje wirtualnej maszyny • Pliki class • Ładowanie, łączenie, inicjalizacja • Wątki i blokady • Kompilacja dla wirtualnej maszyny • Literatura

  3. Wstęp

  4. Bytecode • Zagadka: co robi poniższy program Method void main(java.lang.String[]) 0 getstatic #2 3 ldc #3 5 invokevirtual #4 8 return

  5. Wstęp – historia Javy • Cel powstania (początek prac – 1991) • tworzenie oprogramowania dla urządzeń pracujących w sieci • Wymagania / konsekwencje • wspomaganie wielu architektur • bezpieczeństwo • krótki kod • Pierwsza przeglądarka: HotJava (1994)

  6. Wirtualna Maszyna Javy • Wirtualny komputer posiadający: • pamięć • zestaw instrukcji (assembler ~ bytecode) • wewnętrzne typy danych • Specyfikacja definiuje tylko to co niezbędne • format plików class • instrukcje

  7. Struktura JVM

  8. Typy danych

  9. Typy podstawowe (primitive) • numeryczne • całkowite (integral) • byte(8-bit), short(16-bit), int(32-bit), long(64-bit) • char(16-bit) • zmienno-przecinkowe (floating-point) • float(32-bit), double(64-bit) • boolean • true / false • returnAddress • wskaźnik do instrukcji JVM • używany przez jsr (jump subroutine), ret, jsr_w • jedyny typ nie posiadający swojego odpowiednika w jęz. Java

  10. Typy podstawowe (c.d.) • byte, short, int, long– ze znakiem, dopełnienie do dwóch • char– bez znaku, Unicode • float, double– zgodne z IEEE 754 • +0.0, -0.0 • +∞, -∞ • +0.0 == -0.0ale1.0/0.0 = +∞oraz1.0/-0.0 = -∞ • NaN – Not a Number • reprezentuje wynik błędnej operacji takiej jak dzielenie przez zero (?) • w przeciwieństwie do wszystkich innych wartości jest nieuporządkowany(wszystkie porównania dowolnej wartości z NaN dają false;NaN≠NaN) • boolean – wyrażenia kompilowane są tak, aby używały typu int • tablice typu boolean– dostęp przezbaloadorazbastore • w implementacji Sun’a boolean zajmuje 8 bitów

  11. Typy referencyjne • Wartościami są wskaźniki do obiektów • Dzielimy na typy: • klasowe (classtypes) • tablicowe (arraytypes) • interfejsów (interfacetypes) • Specjalna wartość: null • nie jest żadnego określonego typu (ale może być rzutowany na dowolny typ) • specyfikacja JVM nie określa żadnej konkretnej wartości kodującej null

  12. Obszary danych czasu wykonania • Osobne dla każdego wątku • rejestr pc(program counter) • stos JVM (JVM stack) • ramki • stos metod typu native • Współdzielone przez wątki • obszar metod (method area) • constant pool • sterta (heap)

  13. Rejestrpc(program counter) • wskaźnik (indeks) do bieżącej instrukcji • każdy wątek posiada własny rejestr pc • dla metod native wartość jest niezdefiniowana

  14. Stos JVM • każdy wątek posiada prywatny stos • tworzony w tym samym czasie, co wątek • analogiczny do stosu z języka C • zmienne, częściowe wyniki, wywoływanie metod i powroty • pamięć obszaru nie musi być ciągła • rozmiar stały lub zmieniany dynamicznie • Sun: pamięć nieciągła, powiększany ale nie zmniejszany, maksymalny rozmiar – parametr „-oss”; ograniczenie na zużycie pamięci, wykrywanie nieskończonych rekursji. • sytuacje wyjątkowe: • podczas wykonania: StackOverflowError • podczas tworzenia wątku: OutOfMemorError

  15. Stos metod typu native • rozmiar stały lub zmieniany dynamicznie • Sun: rozmiar stały – parametr „-ss”, nie sprawdza przepełnienia stosu • sytuacje wyjątkowe • StackOverflowError • OutOfMemoryError

  16. Sterta (heap) • dzielona przez wszystkie wątki • pamięć na instancje klas i tablic • tworzona podczas uruchamiania JVM • zarządzany przez garbage collector * • obiekty nigdy nie są jawnie dealokowane • pamięć obszaru nie musi być ciągła • rozmiar stały lub zmieniany dynamicznie • Sun: rozmiar zmienny, powiększany dynamicznie ale nie zmniejszany; rozmiar początkowy i max. – „-ms” i „-mx” • sytuacje wyjątkowe: • OutOfMemoryError

  17. Obszar metod (method area) • dzielony przez wszystkie wątki • przechowuje: runtime constant pool, dane klas (metody, kod metod, …) • logicznie część sterty, ale twórca VM może nie chcieć żeby obszar ten był zarządzany przez garbage collector • pamięć obszaru nie musi być ciągła • rozmiar stały lub zmieniany dynamicznie • Sun: obsługiwany przez GC, kontrola rozmiaru min, max i init. • sytuacje wyjątkowe: • OutOfMemoryError

  18. Constant pool • posiadany przez wszystkie klasy i interfejsy • reprezentuje tablicę constant_pool z pliku class • używany przy dynamicznym linkowaniu (dynamic linking) • odpowiednik tablicy symboli w konwencjonalnych językach, jednak zawiera więcej danych • alokowany z obszaru metod • sytuacje wyjątkowe: • StackOverflowError, OutOfMemoryError

  19. Ramki • tworzone w momencie wywołania metody • alokowane ze stosu JVM • każda ramka posiada • tablice zmiennych lokalnych • operand stack • referencję do constant pool klasy metody

  20. Ramki – tablica zmiennych lokalnych • pojedyncza zmienna może być typu: • boolean, byte, char, short, int,float, reference, returnAddress • para zmiennych może przechowywać wartości typów: • long, double • wartości long, double nie muszą być wyrównywane do 64-bitów • wykorzystywane do przekazywania parametrów do metod • specjalne znaczenie pozycji nr 0

  21. Ramki – operand stack • służy do • przekazania parametrów dla instrukcji JVM • zwracania wyników instrukcji JVM • zwracania wyników przez metody • np.: iadd …, value1, value2 → …, result • wartości na stosie muszą być odpowiednich typów (sprawdzane podczas weryfikacji plików class) iadd

  22. Ramki (c.d.) • zakończenie wywołania metody: • normalne • nie wystąpił wyjątek • zostaje zwrócona wartość do metody wywołującej (operand stack) • nienormalne, niespodziewane (abrupt) • wystąpił wyjątek nie obsługiwany przez tą metodę • wynik nie zostaje zwrócony

  23. Inne ustalenia • reprezentacja obiektów • arytmetyka zmienno-przecinkowa • specjalnie nazwane metody inicjalizacyjne • nazwy wspomagane przez kompilator (nie są prawidłowymi identyfikatorami) • <init> • odpowiednik konstruktora • instrukcja wywołująca: invokespecial • <cinit> • metoda inicjalizująca klasę lub interfejs • statyczna, bez argumentów • wywoływana bezpośrednio przez JVM, nigdy przez instrukcję JVM

  24. Wyjątki • podniesienie wyjątku powoduje natychmiastową zmianę miejsca wykonania • przerywane jest działanie kolejnych metod, do momentu znalezienia klauzuli catch. Jeśli nie ma odpowiedniego catch to wątek kończy działanie. • jeśli są klauzule finally, to są one wykonywane • klauzule catch oraz finally reprezentowane są przez exception handler

  25. Wyjątki – exception handlers • przechowywane są w tablicy (tablica zapisana jest w pliku class) • pojedynczy exception handler (EH): • określa zakres instrukcji dla których jest aktywny • określa typ obsługiwanego wyjątku • zawiera adres kodu obsługującego ten wyjątek • kolejność EH w tablicy jest ważna • tablica przeglądana jest liniowo

  26. Instrukcje wirtualnej maszyny

  27. Instrukcje • kod instrukcji ma 1 bajt • rożne instrukcje dla poszczególnych typów • np.: iload ładuje na stos zmienną typu int, fload - typu float • zestaw instrukcji nie jest ortogonalny

  28. Instrukcje (c.d.) • rodzaje instrukcji • load oraz store iload, iload_<n>, fload, iconst_<n>, … • arytmetyczne iadd, dsub, … • konwersja typów i2l, i2f, i2d, l2f, l2d, f2d; i2b, i2c, i2s, … • operacje na obiektach new, newarray, arraylength, instanceof, … • operacje na stosie arg. pop, dup, swap, … • instrukcje skoku ifeq, ifnull, tableswitch, goto, jsr, … • metody invokevirtual, return, ireturn, … • podnoszenie wyjątków athrow • synchronizacja monitorenter, monitorexit

  29. Pliki class

  30. Pliki class • Typy danych: u1, u2, u4 • Tablice • tables – zawierają elementy zmiennych rozmiarów (tablica (?)) • arrays – zawierają elementy stałych rozmiarów (tabela (?)) • struktury opisane za pomocą struktur z języka C

  31. Pliki class(c.d.) • Plik class składa się z jednej struktury ClassFile: ClassFile { u4 magic; // identyfikuje pliki class (0xCAFEBABE) u2 minor_version; u2 major_version; u2 constant_pool_count; cp_info constant_pool[constant_pool_count-1]; u2 access_flags; // ACC_PUBLIC, ACC_FINAL, ACC_SUPER, // ACC_INTERFACE, ACC_ABSTRACT u2 this_class; // indeks do tablicy constant_pool u2 super_class; u2 interfaces_count; // liczba implementowanych interfejsów u2 interfaces[interfaces_count]; u2 fields_count; field_info fields[fields_count]; u2 methods_count; method_info methods[methods_count]; // reprezentuje wszystkie zadeklarowane metody // (nie zawiera metod odziedziczonych) u2 attributes_count; attribute_info attributes[attributes_count]; //SourceFile, Deprecated //InnerClasses(?) }

  32. Pliki class(c.d.) • Deskryptory pól FieldDescriptor→ FieldType ComponentType → FieldType FieldType→ BaseType | ObjectType | ArrayType BaseType → B | C | D | F | I | J | S | Z ObjectType → L<classname>; ArrayType → [ComponentType B – byte; C – char; D– double; F – float; I – int; J – long; S – short; Z – boolean np.: doubletablica[][][]→[[[D

  33. Pliki class(c.d.) • Deskryptory metod MethodDescriptor→ (ParameterDescriptor*) ReturnDescriptor ParameterDescriptor → FieldType ReturnDescriptor → FieldType | V V – void np.: ObjectmyMethod(int i,double d,Thread t) (IDLjava/lang/Thread;)Ljava/lang/Object;

  34. Pliki class(c.d.) • Tablica constant_pool zawiera pola typu: • CONSTANT_Class • CONSTANT_Fieldref • CONSTANT_Methodref • CONSTANT_InterfaceMethodref • CONSTANT_String • CONSTANT_Integer • CONSTANT_Float • CONSTANT_Long • CONSTANT_Double • CONSTANT_NameAndType • CONSTANT_Utf8

  35. Pliki class(c.d.) • Pola (fields) field_info { u2 access_flags; u2 name_index; u2 descriptor_index; u2 attributes_cout; attribute_info attributes[attributes_count]; } access_flags: ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL, ACC_VOLATILE, ACC_TRANSIENT attributes[]: m.in.: ConstantValue, Deprecated

  36. Pliki class(c.d.) • Metody method_info { u2 access_flags; u2 name_index; u2 descriptor_index; u2 attributes_cout; attribute_info attributes[attributes_count]; } access_flags: ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL, ACC_SYNCHRONIZED, ACC_NATIVE, ACC_ABSTRACT, ACC_STRICT attributes[]: m.in.:Code, Exceptions, Synthetic, Deprecated

  37. Pliki class(c.d.) • Atrybut Code Code_attribute { u2 attribute_name_index; u4 attribute_length; u2 max_stack; u2 max_locals; u4 code_length; u1 code[code_length]; u2 exception_table_length; { u2 start_pc; u2 end_pc; u2 handler_pc; u2 catch_type; } exception_table[exception_table_length]; u2 attributes_count; attribute_info attributes[attributes_count]; }

  38. Ograniczenia na kod JVM • Statyczne, m.in.: • tablica z kodem musi być niepusta • jedyne dozwolone instrukcje, to te wymienione w specyfikacji • każda instrukcja ze skokiem musi wskazywać na kod instrukcji wewnątrz danej metody • instrukcja anewarray może być używana do tworzenia tablic o maksymalnym wymiarze 255 • …

  39. Ograniczenia na kod JVM (c.d.) • Strukturalne, m.in.: • każda instrukcja może być wykonana tylko z odpowiednią liczbą argumentów i z odpowiednimi typami tych argumentów • jeśli instrukcja może być wykonana w skutek różnych ścieżek wykonania, to stos argumentów (operand stack) musi mieć tą samą głębokość niezależnie od ścieżki • każda instrukcja return musi odpowiadać typowi zwracanemu przez daną metodę • …

  40. Weryfikacja plików class • JVM nie może zakładać poprawności plików class • Co jest sprawdzane: • 0 ≤ rozmiar stosu ≤ max_rozmiar • wszystkie zmienne lokalne są używane prawidłowo • argumenty instrukcji są odpowiednich typów • klasy final nie posiadają podklas • każda klasa (oprócz Object) posiada bezpośrednią nadklasę • …

  41. Ładowanie, łączenie, inicjalizacja

  42. Ładowanie, łączenie, inicjalizacja • Ładowanie (loading) • proces wyszukiwania binarnej reprezentacji klasy lub interfejsu i utworzenie klasy/interfejsu • klasy nie będące tablicami ładowane są przez class loader’a • programista może zdefiniować własny class loader • Łączenie • weryfikacja • „umiejscowienie” danej klasy/interfejsu w aktualnym stanie Wirtualnej Maszyny

  43. Wątki i blokady (locks)

  44. Wątki i blokady (locks) • Niskopoziomowe mechanizmy korzystania przez wątki z pamięci dzielonej • Pamięć: • pamięć główna współdzielona przez wątki • pamięć robocza wątku • Pamięć główna zawiera kopie główne zmiennych • Pamięć robocza zawiera kopie robocze zmiennych • Pamięć główna: jeden obiekt – jedna blokada • Akcje wykonywane przez pamięć główną: • read, write, lock, unlock • Akcje wykonywane wątek: • use, assign, load, store, lock, unlock • Powyższe akcje są atomowe.

  45. Wątki i blokady (locks) • read: (pamięć gł.) kopia główna → pamięć robocza • load: (wątek) pamięć robocza → kopia robocza • use: (wątek) kopia robocza→thread’s execution engine • assign: (wątek) thread’s e.e. → kopia robocza • store: (wątek) kopia robocza → pamięć główna • write: (pamięć gł.) pamięć główna → kopia główna • lock: (wątek, operacja ściśle zsynchronizowana z pamięcią główną) • unlock: (wątek, operacja ściśle zsynchronizowana z pamięcią główną)

  46. Kompilacja

  47. Operand stack i zmienne lokalne iload_0 // push the int in local variable 0 iload_1 // push the int in local variable 1 iadd // pop two ints, add them, push result istore_2 // pop int, store into local variable 2

  48. Stałe, zmienne lokalne, instrukcje skoku void spin() { int i; for (i = 0; i < 100; i++) { ;// Loop body is empty } } Method void spin() 0 iconst_0 // Push int constant 0 1 istore_1 // Store into local variable 1 (i=0) 2 goto 8// First time through don't increment Loop body 5 iinc 1 1 // Increment local variable 1 by 1 (i++) 8 iload_1 // Push local variable 1 (i) 9 bipush 100 // Push int constant 100 11 if_icmplt 5// Compare and loop if less than (i < 100) 14 return // Return void when done

  49. Operacje arytmetyczne, parametry metod int align2grain(int i, int grain) { return ((i + grain-1) &~(grain-1)); } Method int align2grain(int,int) 0 iload_1 // Push i 1 iload_2 // Push grain 2 iadd 3 iconst_1 4 isub 5 iload_2 // Push grain 6 iconst_1 7 isub 8 iconst_m1 9 ixor // (~x == -1^x) 10 iand 11 ireturn

  50. Wywoływanie metod int addTwo(int i, int j) { return i + j; } int add12and13() { returnaddTwo(12,13); } Method int add12and13() 0 aload_0 // Push local variable 0 (this) 1 bipush 12// Push int constant 12 3 bipush 13// Push int constant 13 5 invokevirtual #4// Method Example.addtwo(II)I 8ireturn // Return int on top of operand stack; it is // the int result of addTwo()

More Related