2012-10-31 13 views
8

Da quanto ho capito, throw è un comando jvm primitivo. Quando viene chiamato, la JVM "controlla se lo stack di chiamate corrente può prenderlo". se non può, java semplicemente fa apparire lo stack di chiamata quasi esattamente come se fosse stato chiamato un ritorno. quindi jvm "controlla se lo stack di chiamate corrente può prenderlo" e così via ricorsivamente.In che modo la JVM sa dove rilevare un'eccezione in fase di runtime?

La mia domanda: come è algoritmicamente possibile per JVM sapere dove nello stack di chiamate è possibile rilevare una determinata eccezione? Sono presenti metadati memorizzati in ogni voce dello stack delle chiamate che associano le eccezioni ai blocchi di codice? c'è una struttura di dati statici nell'heap che in qualche modo tiene traccia di questo? perché da qualche parte ci devono essere dati che tengono traccia di ciò.

+1

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

risposta

9

Il JVM specification ha dettagli su questo.

In particolare, section 4.7.3 fornisce dettagli sulla tabella delle eccezioni, ovvero una serie di voci che indicano quali eccezioni sono intercettate tra le istruzioni. Section 3.12 ne fornisce un esempio concreto.

Il modo in cui i metadati vengono mappati nel codice nativo per la JIT è una questione diversa, ovviamente, e specifica per l'implementazione. Ad esempio, potrebbe esserci qualche mappatura da ogni posizione dell'istruzione nel codice JITted nativo fino alla posizione del bytecode originale, a quel punto la tabella delle eccezioni può essere consultata per trovare il gestore destro.

+0

Molto interessante :) – Mik378

1

In generale: quando viene generata un'eccezione, la JVM estrae lo "stack di chiamate". Questo identifica quale bytecode o istruzione macchina è stata eseguita ad ogni livello nello stack di chiamate, insieme alla classe e al metodo associato a tale posizione.

Quindi, per ogni metodo nello stack (a partire dal metodo in cui si è verificata l'eccezione e funzionante all'indietro), la JVM cerca (nell'oggetto classe interno) al mapping della tabella del metodo try/catch ranges to bytecode/machine instruction gamme.

Se viene trovata una corrispondenza nella tabella per un metodo e il tipo di eccezione generata è una classe monitorata nell'intervallo trovato, il controllo viene trasferito al punto di immissione catch, dopo aver impostato l'eccezione in una sorta di posizione dei parametri in modo che la clausola catch possa farvi riferimento.

Se non viene trovata una "corrispondenza" nella tabella, lo stack di chiamate viene effettivamente "spuntato", posizionando il metodo precedente in cima allo stack e la ricerca sopra riportata per una "corrispondenza" nella tabella del metodo precedente degli intervalli try/catch viene ripetuto.

Questo naturalmente è un eccesso di semplificazione. C'è molta logica in più nella gestione degli intervalli finally, ad esempio, e di diversi casi "limite".

Problemi correlati