Je touchais Graal et je ne savais pas ce qu'était l'analyse de l'évasion partielle, alors je l'ai recherchée.
↓ Articles écrits sur Graal / GraalVM https://qiita.com/kinshotomoya/items/39a821dd6a6a52202c0a
L'exemple de code est écrit en scala.
La référence d'objet existe en dehors de la méthode ou dans un thread différent. Lorsqu'il est échappé, vous pouvez faire référence à l'objet à partir d'un nombre non spécifié d'emplacements.
Quand pouvons-nous dire qu'un objet est échappé dans le code réel? Il y a principalement les trois conditions suivantes.
Les références à a, qui est une instance d'Object, peuvent être référencées au-delà de la méthode hoge. Peut également être référencé à partir de la méthode foo
case class Object()
object Test {
def hoge: Object = {
val a = Object()
foo(a)
}
def foo(obj: Object) = ???
}
Les références à l'instance b d'un objet peuvent être référencées au-delà de la méthode hoge. La variable b2 a une référence à l'objet a.
case class Object()
object Test {
def hoge: Object = {
val b = Object()
b
}
val b2 = hoge()
}
En d'autres termes, il est possible de se référer aux instances de l'exemple ci-dessus, a et b, au-delà de la méthode.
Analysez si la référence d'instance s'échappe en dehors de la méthode ou vers un autre thread. Il existe différents algorithmes.
Lorsque l'analyse d'échappement montre que la référence est fermée à l'intérieur de la méthode,
Si l'instance est utilisée uniquement dans la méthode, il est efficace de la stocker dans la zone de pile qui est libérée après la fin de la méthode.
Les références provenant d'un seul thread éliminent le besoin de synchronisation entre les threads.
À la suite de l'analyse d'échappement, le compilateur optimise le code. Un exemple est montré.
J'ai le code suivant.
class Person {
def get(name: String) = {
val person: Person = Person(name)
if (person.name === "hoge") {
}
...
}
}
case class Person(name: String)
Une instance de l'objet Person, person, n'a pas été échappée. Dans de tels cas, le compilateur en ligne et optimise.
class Person {
def get(name: String) = {
// val person: Person = Person(name)
if (name === "hoge") { //En ligne
}
...
}
}
case class Person(name: String)
C'est l'une des fonctionnalités du nouveau compilateur JIT Graal. Il peut être partiellement optimisé.
Si vous avez le code suivant.
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)
L'objet personne n'est pas échappé si cachePerson existe. Le compilateur analyse cela et le corrige au code suivant.
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)
Vous pouvez déplacer val person: Person = Person (name)
sous ʻelse et, si
cachePerson` existe, éliminer l'allocation de mémoire à la zone de tas. Au lieu de cela, il est stocké dans la zone de pile, améliorant l'efficacité du traitement.
Si cachePerson
n'existe pas, la personne sera échappée et stockée dans la zone du tas.
Recommended Posts