2010-09-05 11 views
49

Ich weiß nur, dass die Nicht-Primitiven (die Objekte) auf den Haufen gehen, und Methoden gehen auf den Stapel, aber was ist mit den primitiven Variablen?Gehen Java-Primitive auf den Stack oder den Heap?

--update

Basierend auf den Antworten, konnte ich die Haufen sagen einen neuen Stack und Heap für ein bestimmtes Objekt haben kann? Vorausgesetzt, dass das Objekt primitive und Referenzvariablen hat ..?

+1

Jeder Thread hat seinen eigenen Stapel, nicht jedes Objekt. Wenn es nur einen Thread gibt, dann gibt es nur einen Stack. – Alex

Antwort

77

Primitive definiert lokal wäre auf dem Stapel. Wenn jedoch ein Grundelement als Teil einer Instanz eines Objekts definiert wäre, würde dieses Grundelement auf dem Heap stehen.

public class Test 
{ 
    private static class HeapClass 
    { 
     public int y; // When an instance of HeapClass is allocated, this will be on the heap. 
    } 
    public static void main(String[] args) 
    { 
     int x=1; // This is on the stack. 
    } 
} 

In Bezug auf das Update:

Objekte ihre eigenen Stapel nicht haben. In meinem Beispiel wäre int y tatsächlich Teil jeder Instanz von HeapClass. Wenn eine Instanz von HeapClass zugewiesen wird (z. B. new HeapClass()), werden alle Membervariablen von HeapClass dem Heap hinzugefügt. Da Instanzen von HeapClass auf dem Heap zugewiesen werden, befindet sich int y auf dem Heap als Teil einer Instanz von HeapClass.

Alle im Körper einer beliebigen Methode deklarierten primitiven Variablen befinden sich jedoch auf dem Stapel.

Wie Sie im obigen Beispiel sehen können, befindet sich int x auf dem Stapel, da es in einem Methodenrumpf deklariert ist - nicht als Mitglied einer Klasse.

+0

+1 Danke! Bitte beachten Sie mein neues Update zu der Frage. –

+1

Möglicherweise möchten Sie den Kommentar in Ihrem Code ändern. Im Text sagen Sie, dass 'x' auf dem Stapel ist, aber der Kommentar sagt heap. – musiKk

+0

Guter Fang. Vielen Dank. –

19

Alle lokalen Variablen (einschließlich Methodenargumente) gehen auf den Stapel; Objekte und alle ihre Felder werden im Heap gespeichert. Variablen sind immer Primitive oder Referenzen zu Objekten.

Java-Implementierungen können Objekte auf dem Heap tatsächlich so speichern, dass sie weiterhin der Spezifikation entsprechen. Ähnlich können lokale Variablen in Registern gespeichert werden oder durch Optimierung unscharf werden.

+0

+1 Danke! Bitte beachten Sie mein neues Update zu der Frage. –

10

Primitive können an beiden Orten gefunden werden.

außer Sie sollten nicht wirklich kümmern, es sei denn, Sie bauen eine JVM. Ein wirklich schlauer Optimierer könnte entscheiden, dass das Foo, auf das f zeigt, niemals aus dem Hauptbereich austritt und niemals an eine andere Funktion weitergegeben wird, die es sicher auf dem Stapel zuweisen kann.

In Bezug auf das Update:

Der Stack und den Heap sind nicht zu unterscheiden, was in ihnen gespeichert ist, sondern vielmehr die Operationen für sie zur Verfügung gestellt. Der Stapel erlaubt Ihnen, ein Stück Speicher in einer LIFO-Weise zuzuordnen, Sie können ein Stück nicht freigeben, bis alle Teile, die jünger als es sind, ebenfalls freigegeben wurden. Dies passt sich bequem an, wie ein Call-Stack verwendet wird. Sie können alles auf den Stapel legen, solange es in Ordnung ist, dass das Ding verschwindet, wenn Ihre Funktion zurückkehrt. Dies ist eine Optimierung, da sie sehr schnell von einem Stapel zugewiesen und freigegeben wird, da sie nur auf diese Weise unterstützt wird. Man könnte alle lokalen Variablen für eine Funktion auf dem Heap in einer Implementierung speichern, wenn man möchte. Der Heap ist flexibler und folglich teurer zu verwenden. Es wäre nicht richtig zu sagen, dass ein Objekt einen Stack und einen Heap hat, wie ich bereits sagte, was den Stack vom Heap unterscheidet, ist nicht das, was drin ist, sondern die verfügbaren Operationen.

+0

+1 Danke! Bitte beachten Sie mein neues Update zu der Frage. –

+0

@Logan: '// f.x ist wahrscheinlich auf dem Haufen' -> Sagen Sie, es hängt von der JVM-Implementierung ab? – realPK

7

Primitive Werte werden auf dem Stapel zugewiesen, sofern sie keine Felder eines Objekts sind. In diesem Fall werden sie auf den Heap gesetzt. Der Stapel wird für die Auswertung und Ausführung verwendet, daher ist es nicht sinnvoll zu sagen, dass Objekte mit primitiven Feldern einen Stapel haben - sie werden immer noch als Teil des Stapels betrachtet. Sogar Stack Objekte sind auf dem Heap zugeordnet.

Verwandte Themen