2013-11-21 18 views
7

Sembra una domanda stupida, ma ho trovato che è difficile farlo bene. Ho chiesto a persone diverse ma non ho potuto ottenere una risposta ideale.Cosa succede dopo che un metodo viene chiamato in Java

Voglio sapere che cosa succede dopo aver chiamato un metodo normale in Java (Fornito in un ambiente a thread singolo).

mia comprensione è che:

  1. Tutte le variabili di stack correnti sono poped-up e memorizzati da qualche parte (dove?)
  2. La chiamata al metodo corrente arresta
  3. Gli argomenti del metodo appena chiamato sono spinti allo stack
  4. Il codice del metodo viene eseguito
  5. Al termine dell'esecuzione del metodo, lo stack viene nuovamente svuotato e il vecchio contenuto dello stack viene nuovamente ripristinato. (Cosa è successo se la funzione restituisce un valore?).
  6. Il codice continua con il metodo di chiamata.

Questa è una risposta molto incompleta e probabilmente errata. Qualcuno può fornire una descrizione più dettagliata?

Molte grazie.

+4

Sono quasi sicuro che lo stack non è stato svuotato, altrimenti non avresti mai ottenuto StackOverflowException. – MightyPork

+0

I passaggi (1) e (5) non si verificano. E c'è un altro passo, che è quello di spingere il valore di ritorno del metodo in pila (a meno che non sia ovviamente vuoto). –

+1

Leggi http://www.javaworld.com/jw-06-1997/jw-06-hood.html - è tutto descritto in dettaglio. –

risposta

3

n, che in realtà è abbastanza precisa:

1) correnti variabili di stack rimangono sulla pila

2) Il metodo corrente sospende

3) Gli argomenti del metodo appena chiamato sono spinti lo stack

4) il codice del metodo viene eseguito

5) Dopo il metodo terminato l'esecuzione, abbiamo pop lo stack. Le variabili di stack del metodo chiamato non sono più valide - non sono più "esistenti" a questo punto.

6) Passiamo il valore di ritorno (se presente) per il chiamante

7) Codice prosegue con il metodo chiamante. Tutte le sue variabili dello stack rimangono intatte.

==============================

APPENDICE:

@ Kevin -

  • Concettualmente, penso che tu abbia capito bene. Ho chiarito alcuni punti, spero che questo aiuti.

  • Il collegamento di David Wallace è molto buono se si desidera approfondire il modo in cui JVM implementa il "metodo di chiamata".

  • Ecco una buona panoramica su come "una pila" funziona. Qualsiasi stack, chiamando qualsiasi subroutine - non solo Java: http://en.wikipedia.org/wiki/Call_stack

  • Infine, Marko Topolnik è corretto."La realtà" è quasi sempre abbastanza complessa da non prestarsi a una risposta semplice, a taglia unica. Ma penso che la tua comprensione sia buona. Almeno al livello di 10.000 piedi.

IMHO ...

+0

che dire di spingere/scoppiare l'indirizzo da dove è stato chiamato? – MightyPork

+0

Che ne pensi? Sì: l'indirizzo viene inviato allo stack quando viene chiamata la funzione e viene estratto dallo stack quando viene restituita la funzione. – paulsm4

1

Per l'interprete, assumendo un metodo di istanza, e prendendo qualche libertà minori:

  1. Il puntatore oggetto viene utilizzato per fare riferimento all'oggetto, e da lì la Oggetto di classe.
  2. Il puntatore del metodo si trova nell'oggetto Class. (La ricerca per convertire il nome del metodo nell'indice del metodo è stata in gran parte eseguita quando la classe è stata caricata, quindi questa è fondamentalmente solo un'operazione dell'indice dell'array.)
  3. Generalmente una sorta di "marchio" viene inserito nello stack JVM. Ciò conterrebbe il puntatore di istruzioni del chiamante e un puntatore alla base del suo stack. (Molte implementazioni diverse qui.)
  4. La definizione del metodo viene consultata per vedere quanti vars locali sono necessari. Che molti elementi vuoti sono spinti in pila.
  5. Il puntatore dell'oggetto ("questo") è memorizzato in var 0 locale e qualsiasi parms è memorizzato in 1,2,3 ... come appropriato.
  6. Il controllo viene trasferito al metodo chiamato.

Al ritorno, lo stack viene saltato al punto in cui è iniziata la chiamata, qualsiasi valore di ritorno viene inserito nello stack e il controllo viene trasferito al chiamante.

Il codice compilato è concettualmente simile, utilizza solo lo stack "C" e il codice interpretato in un ambiente JITC utilizzerà sia lo stack JVM che lo stack "C".

Problemi correlati