对象一定分配在堆中吗?有没有了解逃逸分析技术?

对象一定分配在堆中吗? 不一定。

随着JIT编译器的发展和逃逸分析技术的成熟,不是所有的对象都必须分配在堆上。实际上,在编译期间,JIT编译器会对代码进行优化。其中一项重要的优化技术是逃逸分析。

逃逸分析是一种分析指针的动态范围的方法,与编译器优化原理中的指针分析和外形分析相关。当变量(或对象)在方法内被分配后,其指针有可能被返回或被全局引用,从而被其他方法或线程引用,这被称为指针(或引用)的逃逸。

简单来说,当一个对象被创建后,它可能被外部代码调用。如果作为参数传递到外部方法中,就称为方法逃逸。

jvm-37.png

除此之外,如果对象可能被外部线程访问,例如赋值给可以在其他线程中访问的实例变量,这种情况被称为线程逃逸。

逃逸分析的好处

  • 栈上分配:如果确定一个对象不会逃逸到线程之外,可以考虑在栈上分配该对象。随着栈帧的出栈,对象占用的内存也会被销毁,从而减轻垃圾收集的压力。
  • 同步消除:线程同步本身是一个相对耗时的操作。如果逃逸分析能够确定一个变量不会逃逸到其他线程,不会被其他线程访问,那么对于该变量的读写就不会存在竞争条件,因此可以安全地消除对该变量的同步操作。
  • 标量替换:如果一个对象的数据是基本数据类型且不可拆分,那么它被称为标量。通过将一个对象拆解成其成员变量的原始类型来访问,这个过程被称为标量替换。如果逃逸分析能够证明一个对象不会被方法外部访问,并且该对象可以被拆解为标量,就可以避免创建对象,直接使用若干个成员变量来代替。这样可以让对象的成员变量在栈上进行分配和读写,提高性能。

标签: java, Java面试题, Java问题合集, Java编程, Java问题精选, Java常见问题