2015-01-24 34 views
7

Więc mam ta metoda, napisany w Javie:Gdzie znajduje się skompilowany kod JIT?

public void myMethod(int y){ 
    int x = 5 + y; 
    doSomething(x); 
} 

i zakładamy, moja aplikacja wywołuje to wiele razy ..

Po uruchomieniu skompilowany kod dla tej metody na Java Virtual Machine, JVM najpierw zinterpretuj metodę. Potem, po pewnym czasie, zdecyduję się skompilować go na język maszynowy, jeśli dobrze zrozumiem.

W tym momencie

zostanie zastąpiony przez kod maszynowy w pamięci? Jeśli zostanie on nadpisany, w jaki sposób rozwiązany zostanie problem różnicy wielkości? Jeśli zostanie zapisane w innym miejscu w pamięci, czy kod bajtowy załadowany do pamięci zostanie zwolniony, czy nie? A także, jeśli kod bajtowy i skompilowany przez jit jest w pamięci, gdy aplikacja ponownie trafi tę metodę, w jaki sposób JVM decyduje się na wykonanie skompilowanego kodu jit zamiast kodu bajtowego?

+0

Wpadłem na pomysł, że tego rodzaju rzeczy będą zależeć od tego, czy używasz komputera z systemem Windows, czy na przykład na pozbawionym pamięci RAM mikrokontroleru. Innymi słowy, zależne od platformy, nie? – Ghostkeeper

+2

Odpowiedź 1: Dlaczego Cię to obchodzi? Odpowiedź 2: JVM przechowuje kod JITCed dla każdej metody w sterty C, połączonej za pomocą tabel w wewnętrznej reprezentacji obiektu klasy. Kod jest usuwany tylko wtedy, gdy kończy się JVM lub w rzadkim przypadku, gdy klasa jest "rozładowana". Wszystko to jest zarządzane przez odpowiednią magię. –

+1

"Stertę C" jest tu naprawdę mylące - jeśli odnosi się do pamięci uzyskanej za pomocą wywołań do malloc (które mogą lub nie muszą być wyrównane do strony), odpowiednie strony musiałyby być oznaczone jako wykonywalne. Bardziej prawdopodobne jest, że JIT przydziela pamięć dla wygenerowanego kodu za pomocą mmap, VirtualAlloc i tym podobnych. –

Odpowiedz

12

HotSpot JVM ma strukturę Method w Metaspace (lub PermGen we wcześniejszych wersjach). Zawiera kod metody, który nigdy nie jest zastępowany i a pointer to compiled code, początkowo NULL, dopóki metoda nie zostanie skompilowana.

sposób może mieć wiele punktów aktu:

  • _i2i_entry - wskaźnik do interpretera kodu bajtowego.
  • _code->entry_point() - punkt wejścia do skompilowanego kodu JIT. Skompilowane metody znajdują się w CodeCache - specjalnym regionie pamięci macierzystej dla dynamicznie generowanego kodu VM.
  • i2c i c2i Adaptery do wywołania skompilowanego kodu z interpretera i odwrotnie. Adaptery te są potrzebne, ponieważ interpretowane metody i skompilowane metody mają różną konwencję wywoływania (sposób przekazywania argumentów, konstruowania ramek itp.)

Metoda kompilowana może zawierać nietypowe pułapki, które powracają do interpretatora w kilka rzadkich przypadków. Co więcej, metoda Java może być dynamicznie rekompilowana wiele razy, więc JVM nie może wyrzucić oryginalnego kodu bajtowego. Nie ma sensu, aby go uwolnić, ponieważ kod bajtowy jest zwykle znacznie mniejszy niż skompilowany kod.

5

Nie, to nie jest nadpisane, ponieważ zazwyczaj nie ma praktycznych korzyści, gdy obie reprezentacje znajdują się w tym samym miejscu. Kod bajtowy JVM to tylko część danych. Kod emitowany przez JIT jest strumieniem natywnych instrukcji procesora (w niektórych architekturach jest to wymagane wyraźnie jako plik wykonywalny).

Zwykle, gdy do wykonania wymagana jest nowa funkcja, kompilator JIT odczytuje kod bajtowy tej funkcji, przydziela pamięć w innym miejscu, wypisuje równoważny kod natywny do tej pamięci, a następnie zwraca wskaźnik funkcji do wpisu nowo wygenerowany kod natywny.

+1

Ponadto: na wielu współczesnych platformach należy jawnie poprosić o * plik wykonywalny * z podsystemu pamięci wirtualnej. Nie ma żadnego powodu, aby kod bajtowy był przydzielany do strony wykonywalnej. –

2

O ile mi wiadomo, The Java® Virtual Machine Specification nie określa żadnego z powyższych.
Jedyne odniesienie do JIT mogę znaleźć w Chapter 3:

[...] Jednym z przykładów takiego tłumacza jest just-in-time (JIT), generator kodu, który generuje instrukcje specyficzne dla platformy tylko po wczytaniu kodu Java Virtual Machine. W tym rozdziale nie poruszono kwestii związanych z generowaniem kodu, tylko te związane ze skompilowaniem kodu źródłowego napisanego w języku programowania Java na instrukcje wirtualnej maszyny Java.

Zgodnie z moim rozumieniem można tego dokonać w różny sposób za pomocą różnych implementacji.

Jednak wydaje mi się mało prawdopodobne, aby pamięć zawierająca kod bajtowy Java została zastąpiona natywnymi instrukcjami procesora, ponieważ instrukcje procesora są technicznie możliwe do wykonania, a kod bajtowy jest po prostu danymi, ponieważ musi zostać zinterpretowany. Nie byłoby to jednak niemożliwe, po prostu bardzo dziwne.

Powiązane problemy