Quando creo un oggetto, viene allocata nuova memoria sia ai campi che ai metodi dell'istanza o solo ai campi dell'istanza


14

Ho una lezione successiva

class Student{

int rollNumber;
int marks;

public void setResult(int rollNumber, int marks){

    this.rollNumber=rollNumber;
    this.marks=marks;   
}

public void displayResult(){

    System.out.println("Roll Number= "+this.rollNumber+"   Marks= "+this.marks);

}
}

Ora creo due oggetti di tipo Studente come segue

Student s1=new Student();
Student s2=new Student();

Ora due diversi set di memoria sono allocati per i campi di istanza. Ora la mia domanda è se la memoria è allocata per i metodi ( setResulte displayResult) due o una volta?

Si prega di vedere la figura seguente e mi potete aiutare a dire quale figura fornisce informazioni corrette.

inserisci qui la descrizione dell'immagine


1
Condividere la tua ricerca aiuta tutti . Dicci cosa hai provato e perché non ha soddisfatto le tue esigenze. Ciò dimostra che hai impiegato del tempo per cercare di aiutarti, ci salva dal ribadire risposte ovvie e, soprattutto, ti aiuta a ottenere una risposta più specifica e pertinente. Vedi anche Come chiedere
moscerino

3
Sto imparando java ... e in tutti i materiali dicono solo che ogni volta che creiamo un oggetto viene allocata una nuova memoria a tutti i campi dell'istanza ... ma nessuno dei materiali dice se verrà allocata memoria fresca per metodi o no
Harish_N,

Risposte:


13

Il codice per metodi fa parte di Class(più concisamente Class<Student>) e viene caricato in memoria al primo caricamento della classe.

Detto questo, quando si esegue qualsiasi metodo viene utilizzata memoria aggiuntiva, per allocare memoria a parametri, variabili locali, risultati di espressioni temporanee, valori di ritorno e così via. Ma tale memoria viene allocata nello stack (la memoria utilizzata durante la creazione di una nuova istanza viene allocata nell'heap .

Secondo la tua domanda, dovrebbe essere chiaro ora che la figura B è corretta (anche se non riflette ciò che accade quando in realtà chiami il metodo).


Ok. Sono chiaro al 90% ora .... Ma un piccolo dubbio .. Supponiamo che se creo 10 oggetti di tipo Studente, solo 1 set di memoria fresca viene assegnato ai metodi presenti nella classe Studente mentre 10 set di memoria fresca sono allocato per memorizzare le variabili di istanza per 10 oggetti .. Ho ragione?
Harish_N,

Giusto. Pensa che non sono solo le proprietà a occupare memoria, c'è un piccolo overhead relativo all'istanza stessa (un'istanza di una classe senza proprietà utilizzerà più di 0 byte di memoria).
SJuan76,

Un'altra cosa ... ho fatto una domanda tenendo a mente java .... Succede la stessa cosa a java .....
Harish_N,

La specifica del linguaggio Java non dice nulla sulla quantità di memoria allocata quando e per quale scopo. Ciò è lasciato all'implementatore e ogni attuatore può scegliere diversamente.
Jörg W Mittag,

6

I campi di istanza (inclusi i campi di supporto della proprietà) ottengono copie N per oggetti N.

I campi statici ottengono una singola copia per classe.

I metodi sono blocchi di bytecode (o dopo JIT, blocchi di istruzioni native) che fanno parte della "immagine" del programma o del segmento di codice eseguibile. I metodi fanno già parte dell'immagine del programma in quanto si trova sul disco. Una volta che l'immagine è stata caricata dal sistema operativo (o CLR), esiste una singola copia condivisa del codice del metodo.

Non fanno parte di "heap" o allocazione di runtime in generale, tranne nei casi in cui è possibile utilizzare il compilatore hostable per compilare nuovi metodi al volo. I metodi non vengono "allocati" come oggetti e non vengono "allocati" rispetto alla creazione dell'oggetto. Esistono semplicemente come parte del programma prima che un singolo oggetto venga mai istanziato. Perfino lambda / delegati non sono assegnati al volo. Il compilatore crea classi su richiesta per implementare questi altri oggetti di codice apparentemente dinamici ed esistono anche come parte dell'immagine del bytecode su disco.

AGGIORNAMENTI per commenti:

Lo standard JVM ha questo da dire:

2.5.4. Area del metodo

Java Virtual Machine ha un'area del metodo condivisa tra tutti i thread Java Virtual Machine. L'area del metodo è analoga all'area di archiviazione per il codice compilato di una lingua convenzionale o analoga al segmento "testo" in un processo del sistema operativo. Memorizza strutture per classe come il pool di costanti di runtime, i dati dei campi e dei metodi e il codice per metodi e costruttori, inclusi i metodi speciali (§2.9) utilizzati nell'inizializzazione di classi e istanze e inizializzazione dell'interfaccia.

L'area del metodo viene creata all'avvio della macchina virtuale. Sebbene l'area del metodo sia logicamente parte dell'heap, le implementazioni semplici possono scegliere di non raccogliere la spazzatura o compattarla. Questa versione della specifica Java Virtual Machine non impone la posizione dell'area del metodo o le politiche utilizzate per gestire il codice compilato. L'area del metodo può essere di dimensioni fisse o può essere espansa come richiesto dal calcolo e può essere contratta se un'area del metodo più ampia diventa superflua. La memoria per l'area del metodo non deve essere contigua.

Quindi è chiaro che (1) sì, le specifiche non dettano come ciò viene fatto, ma (2) è analogo all'area di archiviazione per il codice compilato di un linguaggio convenzionale, ad es. il segmento di testo. Questo è il punto che sto sollevando.


Quello che stai dicendo ha senso, ma è effettivamente garantito da JLS? Normalmente, il JLS offre agli attuatori molta libertà in domande come questa.
Jörg W Mittag,

Non sono sicuro su questo punto, @ JörgWMittag. Potresti avere ragione. Il punto che ho cercato di sottolineare è "new T ()" non alloca una nuova istanza di un metodo. Per quanto riguarda le specifiche di JVM, i classloader memorizzano effettivamente il bytecode nell'heap, e immagino che ci siano possibili scenari in cui le classi stesse vengono istanziate e persino vengono raccolte spazzatura. Ma sono i dettagli di implementazione del runtime e concettualmente, l'heap di cui sto parlando è l'heap "utente". La classe e i metodi non sono considerati dati nel normale contesto dell'utente. Ma dal momento che possiamo anche controllare un classloader da userland, credo di non saperlo.
codenheim,

La JLS non parla nemmeno di un mucchio, vero? È perfettamente legale implementare Java con uno stack dinamico e senza heap anziché uno stack di dimensioni fisse limitate e un heap dinamico. Inoltre, JLS non dice nulla sulla JVM, è perfettamente valido per implementare Java senza una JVM.
Jörg W Mittag,

Ti riferisci a JLS, ma sto parlando di JVM. Lo standard JVM discute sicuramente dell'heap. È necessario fornire un ambito / durata variabile che sfugge all'ambito locale dello stack. Quanto a ciò che è teoricamente possibile, preferisco pensare in termini di "implementazioni note". Sono abbastanza sicuro che implementare una JVM completa senza una primitiva heap sia un lavoro difficile, o addirittura impossibile, dal momento che la JVM non è una macchina stack pura. La mia comprensione delle macchine Forth e di altre architetture pure dello stack è che potrebbe essere possibile se esiste una primitiva per l'accesso variabile casuale, ma non l'ho visto.
codenheim,

@ JörgWMittag - Ho aggiunto alla risposta qualcosa che potrebbe interessare alla nostra discussione. Il punto è che stavo disegnando un'analogia con il tradizionale codice o segmento di testo nei sistemi di runtime convenzionali.
codenheim,

-4

oggetto allocato nella memoria heap. quando l'oggetto viene allocato, lo slot per tutte le variabili di istanza viene creato e distrutto quando l'oggetto viene distrutto. così anche la variabile di istanza viene allocata nella memoria heap. E la variabile locale viene creata nello stack nel momento in cui il viene chiamato il metodo.


1
Questo sembra ripetere solo le informazioni fornite nelle risposte precedenti.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.