2010-04-02 6 views
16

Ich habe gestern eine Frage gesehen, die (für mich) eine andere Frage aufgeworfen hat. Bitte schauen Sie auf den folgenden Code:Felder der Klasse, sind sie im Stapel oder Heap gespeichert?

public class Class1 
{ 
    int A; //as I uderstand, int is value type and therefore lives in the stack 
} 

class Class2 
{ 
    Run() 
    { 
     Class1 instance1 = new Class1(); 
     instance1.A = 10; //it points to value type, but isnt this reference (on heap)? 
    } 
} 

oder beim Erstellen der Instanz von Class1, werden seine Feldtypen auf dem Heap und erstellt? Aber dann verstehe ich nicht, wann es wirklich auf dem Stapel wäre, da fast immer eine Instanz eines Objekts erstellt werden muss, um es zu verwenden.

+0

Klassennamen mit einer Nummer zu starten – cpalmer

+0

nicht Wegthema erlaubt: Sie dort – thelost

+0

durch ungültige Klassennamen haben, wie gut :) – Mirek

Antwort

3

Lokale Struct (Werttyp) Variablen werden auf dem Stack gespeichert, Werttyp-Felder einer Klasse werden auf dem Heap gespeichert.

+7

Es sei denn (1) das lokale Varaiable ist das geschlossene äußere Local einer anonymen Methode oder ein Lambda-Ausdruck oder (2) das Local ist in einem Iteratorblock oder (3) der Jitter beschließt, Register anstelle des Stacks zu verwenden. –

+0

Was passiert mit der Variable instance1, was den Speicher angeht? Es ist ein Referenztyp, ist aber gleichzeitig lokal für die Funktion Run(). Wird instance1 auf Stack oder Heap gespeichert? – RBT

+0

Es tut mir leid @EricLippert für einen anderen Kommentar, aber ich habe versucht, meine vorherige zu bearbeiten, konnte es aber nicht rechtzeitig tun. Um meiner obigen Frage Klarheit zu geben, möchte ich zwei Dinge fragen: 1. wo die Referenzinstanz1 gespeichert wird. instance1 ist nur eine Referenz, die eine Speicheradresse enthält, an der sich die tatsächliche Objektinstanz befindet 2. wo das Objekt, Instanz von Class1, die von instance1 referenziert wird. Hier ist das Objekt eine Instanz von Class1, hat aber einen lokalen Bereich in der Run() - Methode. – RBT

2

Ok int ist ein Werttyp, aber '1' (was ein schrecklicher Name für eine Klasse ist) ist ein Referenztyp. Dies bedeutet, dass jede Instanz von "1" auf dem Heap ist.

36

wie ich sie verstehe, int Werttyp und deshalb lebt in dem Stapel

Ihr Verständnis ist falsch. Werttypen werden als "Werttypen" bezeichnet, da sie nach Wert kopiert werden. Referenztypen heißen "Referenztypen", weil sie als Referenz kopiert werden. Es ist überhaupt nicht wahr, dass "Werttypen immer auf dem Stapel leben". Wenn das wahr wäre, würden sie "Stapeltypen" und "Heap-Typen" genannt werden.

Die Wahrheit ist, dass dies ein Implementierungsdetail ist. Verschiedene Framework-Implementierungen können den Stack und den Heap nach Belieben verwenden. Hier ist, wie die Microsoft-Implementierung macht es:

  • der Wert einer Variablen vom Referenztyp ein Verweis auf Heap-Speicher ist. Eine Referenz ist im Grunde eine 32-Bit- oder 64-Bit-Ganzzahl.
  • Der Wert einer Variablen vom Werttyp ist ihr Wert.
  • Die Werte lokaler Variablen werden im Stapel gespeichert, es sei denn, die lokalen Variablen befinden sich in einem Iteratorblock oder sind geschlossene äußere Variablen einer anonymen Methode oder eines Lambda-Ausdrucks. In diesen Fällen werden die Werte der lokalen Variablen auf dem Heap gespeichert. Es sei denn natürlich die lokalen Variablen können weg optimiert werden, in diesem Fall gibt es überhaupt keinen Speicher. Oder vielleicht können sie registriert werden, in diesem Fall sind sie weder auf dem Stapel noch auf dem Haufen, sie sind in Prozessorregistern.
  • Die Werte von Instanzvariablen von Referenztypen und statischen Variablen werden auf dem Heap gespeichert.

Ist das klar?

Es zeigt auf Werttyp, aber ist diese Referenz (auf Heap) nicht?

Das Feld "A" ist vom Werttyp. Es ist ein Feld und daher wird diese Variable auf dem Heap gespeichert.

Beim Erstellen der Instanz von Class1 werden die Feldtypen auch auf dem Heap erstellt?

Der Speicher für die Instanzvariablen befindet sich auf dem Heap, ja.

Aber dann verstehe ich nicht, wann es wirklich auf dem Stapel wäre, da fast immer Sie eine Instanz von Objekt erstellen müssen, um es Felder zu verwenden.

Es wäre nie auf dem Stapel. Wie ich oben sagte, sind die einzigen Dinge, die auf den Stack gehen, lokale Variablen (und vom Compiler erzeugte Provisorien), die keine geschlossenen Locals einer Lambda oder anonymen Methode sind und sich nicht in einem Iteratorblock befinden. Und natürlich ist der Jitter frei, sie vollständig vom Stapel zu halten und sie in Register zu setzen, wenn es freie Register gibt.

Aber wirklich, ich muss fragen, warum interessiert es dich, was auf dem Stapel geht und was auf dem Haufen geht? Was auf den Stapel kommt, sind Sachen, die wir billig auf den Stapel legen können; alles andere geht auf den Haufen.

+0

Ich habe das Buch von John Sharp, dass "Werttypen auf dem Stapel erstellt werden, während Referenztypen auf dem Heap". Versteh es auch nicht. – Thomas

+0

"Die Werte von Instanz und statischen Variablen werden auf dem Heap gespeichert." Außer für struct-typed Instanzvariablen einer Instanz, die auf dem Stack gespeichert wurde, richtig? – Joren

+2

"Warum interessiert es dich, was auf den Stapel kommt und was auf den Haufen geht" - weil manche Interviewer solche Fragen sehr mögen und viele Leute solche Interviews nicht bestanden haben, weil überall geschrieben wird, dass int-Variablen immer auf dem Stack gespeichert sind, nicht "Die einzigen Dinge, die auf den Stapel gehen, sind lokale Variablen" – Laserson

Verwandte Themen