热点代码
被多次调用的方法 —— 编译整个方法
被多次循环的方法体 —— 编译整个方法
基于采样的热点探测
周期性检查各个线程的栈顶,若某个方法经常出现在栈顶,则为”热点方法“。优点:简单、高效;缺点:不够精确,会收到线程阻塞或其他因素影响结果。
基于计数器的热点探测
为每个方法或(甚至代码块)建立计数器,统计执行次数。超过某个阈值则为”热点方法“。优点:准确、严谨;缺点:麻烦。HotSpot虚拟机采用这种方案。
方法调用计数器: 方法调用统计
回边计数器:循环体统计
方法内联:把目标代码“复制”到发起调用的方法之中,避免发生真实的方法调用
逃逸分析:是一种分析技术,基本行为是分析对象动态作用域:当一个对象在方法中被定义,他可能被外部方法所引用,例如作为调用参数传递到其他方法中这种方式被称作方法逃逸。也有可能被外部线程访问到,比如复制给类变量或可以在其他线程中访问的实例变量,被称作线程逃逸。
如果证明这个对象不会逃逸,即别的方法和线程无法通过任何途径访问到这个对象,则可以进行一些高效优化:
栈上分配:在java堆上分配创建对象的内存空间。垃圾回收会回收不再使用的对象,但回收动作无论是筛选动作还是整理内存空间都很耗时。如果一个对象不会逃逸出方法之外,则在栈上分配后,对象占用空间会随栈帧出栈而销毁。
同步消除:若一个对象不会逃逸出线程,那这个对象的读写就不会有竞争,则针对改变量的同步措施就可以消除。
标量替换:标量,即不可被分解的数据,Java虚拟机中的原始数据类型(int long等数值类型和reference类型等)都不能再分解,都是标量。相对的,如果一个数据可以被分解,那它被称作聚合量,比如Java中的对象就是典型的聚合量。若一个对象被逃逸分析判定不会逃逸,那程序执行时,不必创建对象,而是创建它的如干戈成员变量来替代。