4 Stimmen

Laufzeit vs. Kompilierzeit Speicherzuweisung in Java

Ich bin verwirrt, ob die Speicherzuweisung in Java zur Laufzeit oder zur Kompilierzeit erfolgt.

Zum Beispiel:

class Test{
  int a;
  public Test(){
    a=10;
  }
};

// somewhere else
Test t = new Test();

Es a zur Laufzeit oder zur Kompilierzeit zugewiesen? Wenn zur Kompilierzeit, wie ist es möglich, wie Java läuft auf einer VM, die direkt nimmt kompiliert .class-Dateien?

Auch:

  • Wann ist a den Wert zugewiesen 10 ?

  • Wie funktioniert das mit der Bezugsgröße? t ?

Danke.

9voto

kosa Punkte 65422

Zur Kompilierungszeit erfolgt keine Speicherzuweisung. Nur beim Laden und zur Laufzeit.

Beim Kompilieren werden .class-Dateien erzeugt, das war's.

Denken Sie daran, dass Sie eine Hauptklasse benötigen, um das Programm auszuführen. Wenn Sie Ihr Programm in Java mit einem Klassenpfad zu einer .class-Datei ausführen, gibt es Schritte wie Laden und Verknüpfen usw.,

Classloaders lädt die Dateien in permgen.

Wenn die Hauptmethode aufgerufen wird, wird ein Stapel erstellt und die lokalen Variablen werden dort abgelegt.

Wenn die Laufzeit auf nuevo Es erstellt ein Objekt auf dem Heap und weist dort den erforderlichen Speicher zu, wie er für den Test benötigt wird.

5voto

Peter Lawrey Punkte 511323

Lokalen Variablen und Methodenparametern, wie z. B. Primitiven oder Referenzen, wird zur Kompilierungszeit fiktiv ein Platz auf dem Stack zugewiesen.

Zur Laufzeit ist nicht garantiert, dass dies der Anordnung im Speicher entspricht.

Die Zuweisung von Objekten auf dem Heap erfolgt nur zur Laufzeit.

wie ist es möglich, als Java läuft auf VM, die direkt nimmt kompilieren .class-Datei.

Nur die VM weiß, wie der Code kompiliert wird, so dass es nicht möglich ist, die Speicherzuweisung zur Kompilierungszeit vorzunehmen.

wann ist ein zugewiesener Wert 10

In der Zeile, in der die Zuweisung erfolgt. Da es nicht verwendet wird, kann das JIT es verwerfen, so dass es möglicherweise überhaupt nicht passiert.

Die gleiche Frage stellt sich auch für die Bezugsgröße t.

t zugewiesen wird, wenn die = ist, nachdem das Objekt konstruiert wurde.

1voto

alvonellos Punkte 999

Nun, dies ist ein bisschen ein Doozy und ich bin nicht sicher, dass Sie die genaue Antwort, die Sie aus diesem gesamten Thread wollen, da wirklich, was Sie fragen, ist ein großer Diskurs in den Interna des Compilers, und die meisten Menschen wirklich nicht interessiert.

In den meisten Fällen verwendet der Java-Compiler eine automatische Speicherverwaltung, so dass es wirklich am Compiler liegt, zu bestimmen, was er tut und was nicht, und dies kann sich von Version zu Version ändern.

Doch bevor ich dies erkläre, möchte ich meine Notation verdeutlichen:

  1. Ich werde [Object] verwenden, wenn ich mich auf ein Java-Objekt beziehe, das kein Primitiv ist.
  2. Ich werde [object] verwenden, wenn ich mich auf einen Speicherplatz beziehe, der einen Wert und einen Bezeichner hat.
  3. Ich werde [primitiv] verwenden, um auf ein [Objekt] zu verweisen, das aus einem der primitiven Typen in Java besteht (int, double, float, und so weiter, außer string)
  4. String ist ein Sonderfall in Java, und obwohl er ein Objekt ist, kann er anders als andere Objekte behandelt werden.

    Ein [Objekt] hat eine besondere Eigenschaft. Es hat einen Wert und einen Bezeichner, und der Prozess, durch den ein Bezeichner in einen Wert aufgelöst wird und zu welchem Zeitpunkt dies geschieht, hängt von der Art der Bindung ab.

    Es gibt die statische Bindung, bei der die Bindung zur Kompilierzeit aufgelöst werden kann und deren Wert oder Methode zur Kompilierzeit bekannt ist. Dies wird auch als "frühe" Bindung bezeichnet. Zum Beispiel.

    int a = 0; // UND //ein direkter Funktionsaufruf, wie print();

    Es gibt auch die dynamische Bindung, bei der die Bindung zwischen einem Bezeichner und einem Wert oder einem Unterprogramm zu einem Programm erst zur Laufzeit erfolgen kann. Dies wird auch als "späte" Bindung bezeichnet. Ein Beispiel.

    public void foo(java.util.List list) { list.add("bar"); }

    Es gibt auch eine hybride Art der Bindung, aber darüber werde ich nicht sprechen, weil ich Java noch nicht entdeckt habe, um es zu haben.

    Bindung ist auch sehr eng mit Scoping verbunden, d. h. mit der Vorstellung, dass eine Variable in einem bestimmten Bereich "lebt". Das ist ein Thema, auf das ich nicht näher eingehen möchte (Scoping ist ein ziemlicher Brocken) und das diesen Beitrag eher zu einem Roman als zu einer Novelle macht.

    Die Art und Weise, wie die Speicherzuweisung in Java funktioniert, hängt von einigen Dingen ab:

    1. Wenn der Verweis auf ein [Objekt], [Objekt] oder [Primitiv] zur Kompilierungszeit bekannt ist und eine statische Bindung möglich ist, dann wird der Compiler wahrscheinlich zur Kompilierungszeit Speicher für diese Objekte zuweisen (beachten Sie, dass ich keine Klammern verwendet habe).

    2. Wenn der Verweis auf ein [Objekt], [Objekt] oder [Primitiv] zur Kompilierungszeit nicht bekannt ist und eine dynamische Bindung verwendet werden muss, wird der Compiler wahrscheinlich zur Laufzeit Speicher für diese Objekte zuweisen.

    Die Art und Weise, wie Java zur Laufzeit zugewiesene Objekte behandelt, hängt davon ab, welche Bindung für welchen Typ verwendet wurde.

    1. Statische Bindung
      • Bei Objekten, die eine Art von [Object] sind, werden ihre Referenzen zur Kompilierzeit auf dem Stack abgelegt, während ihr Speicher zur Laufzeit auf dem Heap zugewiesen wird. (träge).
      • Objekte, die eine Art von [Primitiv] sind, werden zur Laufzeit gebunden und zugewiesen.
      • Strings sind ein Sonderfall, werden aber im Allgemeinen wie ein [Objekt] behandelt.
    2. Späte Bindung
      • Die Zuweisung auf dem Stack und Heap erfolgt zur Laufzeit.

    Kurzum: Machen Sie sich keine Sorgen. Es bereitet Ihnen große Kopfschmerzen, dies zu tun.

    Sollte ich mich in irgendeiner Hinsicht irren, kann mir das bitte jemand mitteilen. Ich bin ein bisschen eingerostet.

1voto

Jack Punkte 11

In Java wird eine Klasse nicht geladen, es sei denn, ihr Objekt wird erstellt, die zur Laufzeit erstellt werden, so dass alle Mitgliedsvariablen wie "a" in Ihrem erhalten Platz, wenn die Klasse geladen wird, das Gleiche gilt für das Objekt wird Platz zur Laufzeit zugewiesen werden.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X