2012-10-31 17 views
8

Z mojego zrozumienia, throw jest pierwotnym poleceniem jvm. Po wywołaniu JVM "sprawdza, czy bieżący stos wywołań może go złapać". jeśli nie, to java po prostu wyrzuca stos wywołań prawie dokładnie tak, jak gdyby został wywołany zwrot. następnie jvm "sprawdza, czy bieżący stos wywołań może go złapać" itd. w rekursywnie.W jaki sposób JVM wie, gdzie można złapać wyjątek w czasie wykonywania?

Moje pytanie: w jaki sposób algorytmicznie JVM może wiedzieć, gdzie w stosie wywołań może złapać dany wyjątek? Czy istnieją metadane zapisane w każdym odwołaniu do przypisania stosu wywołań do bloków kodu? czy istnieje statyczna struktura danych w stercie, która w jakiś sposób śledzi to? ponieważ gdzieś musi być śledzenie danych.

+1

powiązane: http://stackoverflow.com/questions/10301244/how-is-multi-catch-implemented-in-java-7 – assylias

Odpowiedz

9

Szczegóły na ten temat zawiera JVM specification.

W szczególności section 4.7.3 podaje szczegółowe informacje na temat tabeli wyjątków, która jest serią wpisów informujących, które wyjątki są przechwytywane między którymi instrukcjami. Section 3.12 podaje konkretny przykład tego.

Sposób odwzorowania tych metadanych na kod macierzysty dla JIT to oczywiście inna kwestia - i związane z konkretną implementacją. Na przykład może istnieć odwzorowanie z każdej lokalizacji instrukcji w macierzystym kodzie JIT z powrotem do pierwotnej lokalizacji kodu bajtowego, w którym to momencie można zapoznać się z tabelą wyjątków, aby znaleźć odpowiednią obsługę.

+0

Bardzo interesujące :) – Mik378

1

Mówiąc ogólnie: po wyrzuceniu wyjątku JVM wyodrębnia "stos wywołań". Określa, który kod bajtowy lub instrukcja maszyny były wykonywane na każdym poziomie stosu wywołań, wraz z klasą i metodą związaną z tą lokalizacją.

Następnie, dla każdej metody w stosie (zaczynając od metody, w której wystąpił wyjątek i pracując wstecz), JVM wyszukuje (w obiekcie klasy wewnętrznej) przy mapowaniu tabeli metody próbkowania/wychwytywania zakresów na kod bajtowy/instrukcje maszynowe zakresy.

Jeśli w tabeli dla metody znajduje się "dopasowanie", a typ zgłaszanego wyjątku jest klasą monitorowaną w znalezionym zakresie, to sterowanie jest przesyłane do punktu wejścia catch po ustawieniu wyjątku do pewnego rodzaju położenia parametru, aby klauzula catch mogła się do niego odwoływać.

Jeśli w tabeli nie znaleziono "dopasowania", to stos wywoławczy jest skutecznie "popping", umieszczając następną wcześniejszą metodę na szczycie stosu, a powyższe wyszukiwanie "dopasowania" w tabeli wcześniejszych metod zakresów try/catch jest powtarzany.

To oczywiście nadmierne uproszczenie. Istnieje wiele dodatkowych logik związanych z obsługą zakresów, na przykład, i kilka przypadków "krawędzi".

Powiązane problemy