Ich verstehe, dass jeder Thread seinen eigenen hat stack
. Primitive Typen und Referenzen werden auf dem Stapel gespeichert, und es wird kein Objekt auf dem Stapel gespeichert.
Meine Fragen sind:
- Wie viel kann ein Stapel wachsen? (wie bei den Parametern -
Xms
und -Xmx
) - Können wir sein Wachstum begrenzen?
- Hat der Stapel einen Standard-Minimal- und Maximalwert?
- Wie funktioniert die Speicherbereinigung auf dem Stapel?
Antworten:
Wie viel kann ein Stapel wachsen?
Sie können eine VM-Option mit dem Namen verwenden
ss
, um die maximale Stapelgröße anzupassen. Eine VM-Option wird normalerweise mit -X {Option} übergeben. Sie können alsojava -Xss1M
die maximale Stapelgröße auf 1 MB festlegen.Jeder Thread hat mindestens einen Stapel. Einige Java Virtual Machines (JVM) fassen den Java-Stack (Java-Methodenaufrufe) und den nativen Stack (native Methodenaufrufe in VM) in einem Stapel zusammen und führen das Abwickeln des Stapels mithilfe eines Managed to Native-Frames durch, der als M2NFrame bezeichnet wird. Einige JVMs halten zwei Stapel getrennt. In
Xss
den meisten Fällen wird die Größe des Java-Stacks festgelegt.Für viele JVMs legen sie unterschiedliche Standardwerte für die Stapelgröße auf verschiedenen Plattformen fest.
Können wir dieses Wachstum begrenzen?
Wenn ein Methodenaufruf auftritt, wird ein neuer Stapelrahmen auf dem Stapel dieses Threads erstellt. Der Stapel enthält lokale Variablen, Parameter, Rücksprungadresse usw. In Java können Sie niemals ein Objekt auf den Stapel legen, sondern nur die Objektreferenz auf dem Stapel speichern. Da Array auch ein Objekt in Java ist, werden Arrays auch nicht im Stapel gespeichert. Wenn Sie also die Anzahl Ihrer lokalen primitiven Variablen und Parameter reduzieren, indem Sie sie in Objekte gruppieren, können Sie den Speicherplatz auf dem Stapel reduzieren. Tatsächlich wirkt sich die Tatsache, dass wir Objekte nicht explizit auf den Java-Stapel legen können, auf die Leistung aus (Cache-Fehler).
Hat der Stapel einen Standard-Minimalwert oder einen Standard-Maximalwert?
Wie ich bereits sagte, sind verschiedene VMs unterschiedlich und können sich über Versionen ändern. Siehe hier .
Wie funktioniert die Speicherbereinigung auf dem Stapel?
Garbage Collections in Java sind ein heißes Thema. Die Speicherbereinigung zielt darauf ab, nicht erreichbare Objekte auf dem Heap zu sammeln . Das braucht also eine Definition von "erreichbar". Alles auf dem Stapel ist Teil der Root-Set-Referenzen in GC. Alles, was von jedem Stapel jedes Threads aus erreichbar ist, sollte als live betrachtet werden. Es gibt einige andere Stammsatzreferenzen, wie Thread-Objekte und einige Klassenobjekte.
Dies ist nur eine sehr vage Verwendung von Stack auf GC. Derzeit verwenden die meisten JVMs einen Generations-GC. Dieser Artikel enthält eine kurze Einführung in Java GC. Und kürzlich habe ich einen sehr guten Artikel über den GC auf .net gelesen . Der GC auf oracle jvm ist ziemlich ähnlich, daher denke ich, dass Ihnen das auch helfen könnte.
quelle
java -Xss 100M -jar testing.jar
warf den Fehler "Ungültige Thread-Stapelgröße: -Xss Fehler: Java Virtual Machine konnte nicht erstellt werden." hat aber gutjava -Xss100M -jar testing.jar
funktioniert. Ausführen von Windows 10 64-Bit mit Java "1.8.0_112". Sollte Ihr Beitrag bearbeitet werden, um den Platz zu entfernen?Wie Sie sagen, werden lokale Variablen und Referenzen auf dem Stapel gespeichert. Wenn eine Methode zurückkehrt, wird der Stapelzeiger einfach dorthin zurückgesetzt, wo er vor dem Start der Methode war, dh alle lokalen Daten werden "vom Stapel entfernt". Daher ist auf dem Stapel keine Speicherbereinigung erforderlich, die nur im Heap erfolgt.
So beantworten Sie Ihre spezifischen Fragen:
quelle