Ich berührte Graal und wusste nicht, was die partielle Fluchtanalyse war, also schlug ich nach.
↓ Artikel über Graal / GraalVM https://qiita.com/kinshotomoya/items/39a821dd6a6a52202c0a
Der Beispielcode ist in Scala geschrieben.
Die Objektreferenz existiert außerhalb der Methode oder in einem anderen Thread. Bei Escapezeichen können Sie von einer nicht festgelegten Anzahl von Stellen auf das Objekt verweisen.
Wann können wir sagen, dass ein Objekt im eigentlichen Code maskiert ist? Es gibt hauptsächlich die folgenden drei Bedingungen.
Verweise auf a, eine Instanz von Object, können über die hoge-Methode hinaus referenziert werden. Kann auch über die foo-Methode referenziert werden
case class Object()
object Test {
def hoge: Object = {
val a = Object()
foo(a)
}
def foo(obj: Object) = ???
}
Verweise auf Instanz b eines Objekts können über die Hoge-Methode hinaus referenziert werden. Die Variable b2 hat einen Verweis auf Objekt a.
case class Object()
object Test {
def hoge: Object = {
val b = Object()
b
}
val b2 = hoge()
}
Mit anderen Worten ist es möglich, über das Verfahren hinaus auf die Instanzen des obigen Beispiels a und b zu verweisen.
Analysieren Sie, ob die Instanzreferenz außerhalb der Methode oder in einen anderen Thread maskiert wird. Es gibt verschiedene Algorithmen.
Wenn die Escape-Analyse zeigt, dass die Referenz innerhalb der Methode geschlossen ist,
Wenn die Instanz nur innerhalb der Methode verwendet wird, ist es effektiv, sie im Stapelbereich zu speichern, der nach dem Ende der Methode freigegeben wird.
Referenzen von nur einem Thread machen eine Synchronisation zwischen Threads überflüssig.
Als Ergebnis der Escape-Analyse optimiert der Compiler den Code. Ein Beispiel wird gezeigt.
Ich habe den folgenden Code.
class Person {
def get(name: String) = {
val person: Person = Person(name)
if (person.name === "hoge") {
}
...
}
}
case class Person(name: String)
Eine Instanz des Person-Objekts, person, wurde nicht maskiert. In solchen Fällen inline und optimiert der Compiler.
class Person {
def get(name: String) = {
// val person: Person = Person(name)
if (name === "hoge") { //In der Reihe
}
...
}
}
case class Person(name: String)
Dies ist eine der Funktionen des neuen JIT-Compilers Graal. Es kann teilweise optimiert werden.
Wenn Sie den folgenden Code haben.
class Person {
def get(name: String) = {
val person: Person = Person(name)
val cachePerson = Cache.get(name)
if (cachePerson.isDefined) {
cachePerson
} else {
addToCache(person)
person
}
}
}
case class Person(name: String)
Die Objektperson wird nicht maskiert, wenn cachePerson vorhanden ist. Der Compiler analysiert dies und korrigiert es auf den folgenden Code.
class Person {
def get(name: String) = {
val cachePerson = Cache.get(name)
if (cachePerson.isDefined) {
cachePerson
} else {
val person: Person = Person(name)
addToCache(person)
person
}
}
}
case class Person(name: String)
Sie können "val person: Person = Person (name)" unter "else" verschieben und, falls "cachePerson" vorhanden ist, die Speicherzuordnung zum Heap-Bereich entfernen. Stattdessen wird es im Stapelbereich gespeichert, wodurch die Verarbeitungseffizienz verbessert wird.
Wenn cachePerson
nicht existiert, wird die Person maskiert und im Heap-Bereich gespeichert.
Recommended Posts