Java的转义解析是什么意思?
引言
在使用Graal时,我遇到了部分转义解析的问题,完全不知道该怎么处理,于是做了一些调查记录下来的笔记。
以下是一篇关于Graal・GraalVM的文章。
https://qiita.com/kinshotomoya/items/39a821dd6a6a52202c0a
示例代码使用scala编写。
逃逸是指
当对象的引用存在于方法之外或不同的线程时。
如果进行逃逸,就可以从多个不特定的地方引用到对象。
逃逸的条件
在实际的代码中,我们如何确定对象何时被逃逸?
主要有以下三个条件。
-
- 在方法的参数中指定
- 通过return语句返回(指定返回值)
1. 在方法的参数中指定
对于作为Object实例的a的引用,可以在hoge方法之外引用。
也可以在foo方法中引用。
case class Object()
object Test {
def hoge: Object = {
val a = Object()
foo(a)
}
def foo(obj: Object) = ???
}
2. 使用return返回(指定为返回值)
对象b对实例的引用可以通过hoge方法来引用。
变量b2持有对对象a的引用。
case class Object()
object Test {
def hoge: Object = {
val b = Object()
b
}
val b2 = hoge()
}
换句话说,上述例子中的实例a和b可以在方法之外进行引用。
转义解析是什么?
分析实例引用是否逸出到方法外或其他线程中。有各种算法。
如果没有经过转义会被解析成什么?
透過進行转义分析后,发现引用已被封闭在方法内部。
1. 将实例存储在栈中而不是堆中。
如果只在方法内部使用实例,将其存储在方法结束后会被释放的堆栈空间中会更有效。
2. 在执行方法时,忽略不必要的同步。
如果只从单个线程进行引用,则不需要线程间同步。
最优化案例
逃逸分析的结果,编译器会对代码进行优化。这是一个例子。
将其内联化
有如下代码。
class Person {
def get(name: String) = {
val person: Person = Person(name)
if (person.name === "hoge") {
}
...
}
}
case class Person(name: String)
对于作为Person对象的实例的person未被转义。
在这种情况下,编译器会进行内联和优化。
class Person {
def get(name: String) = {
// val person: Person = Person(name)
if (name === "hoge") { // インライン化
}
...
}
}
case class Person(name: String)
某些逃逸分析
Graal是新一代的JIT编译器,其特点之一是可以进行部分优化。
如果有以下的代码。
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)
如果存在cachePerson,则对象person不会被逃逸。
编译器会分析此情况并将其转换为以下代码。
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)
如果存在cachePerson, 可以将person: Person = Person(name)移动到else语句中,这样就可以省去在堆内存中分配内存的操作。相反,它会被存储在栈内存中,从而提高了处理效率。
如果cachePerson不存在,person会被逃逸并存储在堆区域。
请参考
-
- https://www.slideshare.net/jyukutyo/graal-in-graalvm-a-new-jit-compiler
-
- https://docs.oracle.com/javase/jp/11/vm/java-hotspot-virtual-machine-performance-enhancements.html#GUID-6BD8FCB5-995B-4AE9-BFAA-B2C7DE2BA5CD
-
- https://www.weblio.jp/wkpja/content/%E3%82%A8%E3%82%B9%E3%82%B1%E3%83%BC%E3%83%97%E8%A7%A3%E6%9E%90_%E3%82%A8%E3%82%B9%E3%82%B1%E3%83%BC%E3%83%97%E8%A7%A3%E6%9E%90%E3%81%AE%E6%A6%82%E8%A6%81
- https://gist.github.com/kawasima/32b8097163029d452553e4ae5b8e070b