• java栈帧


    栈帧:
    局部变量表:保存函数的参数以及局部变量用的,局部变量表中的变量只在当前函数调用中有效,当函数调用结束后,随着函数栈帧的销毁,局部变量表也会随之销毁。
    操作数主要用于保存计算过程的中间结果,同时作为计算过程中变量临时的存储空间。只支持出栈入栈操作。
    帧数据区:栈帧需要一些数据来支持常量池解析、正常方法返回和异常处理等。在帧数据区中保存着访问常量池的指针,方便程序访问常量池。
                       此外,当函数返回或者出现异常时,虚拟机必须恢复调用者函数的栈帧,并让调用者函数继续执行下去。
                       对于异常处理,虚拟机必须有一个异常处理表,方便在发生异常的时候找到处理异常的代码,因此异常处理表也是帧数据区中重要的一部分

    栈上分配:优化技术
    基本思想:对于那些线程私有的对象,可以将它们打散分配在栈上,而不是分配在堆上
                       分配在栈上的好处在于函数调用结束后可以自行销毁,而不需要垃圾回收器的介入,从而提高系统的性能
    技术基础:逃逸分析
                       逃逸分析的目的是,判断对象的作用域是否有可能逃逸出函数体
    /**
    * Created by wb-xxd249566 on 2017/3/31.
    */
    public class EscapeAnalysis {
    private static User u;
    public static void alloc(){
    u = new User();
    u.id=5;
    u.name="xuexd";
    }
    }
    对象User u是类的成员变量,该字段有可能被任何线程访问,因此属于逃逸对象。
    /**
    * Created by wb-xxd249566 on 2017/3/31.
    */
    public class EscapeAnalysis {

    public static void alloc(){
    User u = new User();
    u.id=5;
    u.name="xuexd";
    }
    }
    在此处,User以局部变量的形式存在,并且该对象并没有被alloc()函数返回,或者出现了任何形式的公开,因此它未发生逃逸
    对于这种情况,虚拟机就有可能将User分配在栈上,而不是堆上。
    /**
    * Created by wb-xxd249566 on 2017/3/31.
    */
    public class OnStackTest {
    public static class User{
    public int id = 0;
    public String name = "";
    }

    public static void alloc(){
    User u = new User();
    u.id = 5;
    u.name = "xuexd";
    }

    public static void main(String[] args) throws InterruptedException{
    long b = System.currentTimeMillis();
    for (int i=0;i<100000000;i++){
    alloc();
    }
    long e = System.currentTimeMillis();
    System.out.println(e-b);
    }
    }
    运行使用参数:-server -Xmx10m -Xms10m -XX:+DoEscapeAnalysis -XX:+PrintGC -XX:-UseTLAB -XX:+EliminateAllocations
    -server        在Server模式下,才可以启用逃逸分析
    -XX:+DoEscapeAnalysis        启用逃逸分析技术
    -Xmx10m -Xms10m                指定堆空间最大为10MB,显然,如果对象在堆上分配,必然会引起大量的GC
    -XX:+EliminateAllocations       开启标量替换(默认打开),允许对象打散分配在栈上,比如对象拥有id和name俩个字段,那么这俩个字段将会被视为俩个独立的局部变量进行分配
    -XX:-UseTLAB                        关闭TLAB
    只有一次GC输出,程序就执行完毕了,说明在执行过程中,User对象的分配过程被优化了。
    将参数设为-XX:-EliminateAllocations,即关闭标量替换后,则疯狂打印GC:
     
     说明栈上分配依赖逃逸分析和标量替换的实现
    对于大量的零散小对象,栈上分配提供了一种很好的对象分配优化策略,栈上分配速度快,并且可以有效避免垃圾回收带来的负面影响
    但由于和堆空间相比,栈空间较小,因此对于大对象无法也不适合在栈上分配

  • 相关阅读:
    微信小程序支付、退款
    阿里云虚拟主机配置HTTPS
    日本的医保制度
    贫困与抑郁、焦虑之间的联系与机制
    opencv实战-识别信用卡
    pandas常用命令-学习整理
    kubernates部署(二进制包部署方式)
    kubernates部署(kubeadm 部署方式)
    MySQL的锁机制
    Unity UI适配 之 GridLayoutGroup组件下的内容适配(进度条适配)
  • 原文地址:https://www.cnblogs.com/xxdfly/p/6652410.html
Copyright © 2020-2023  润新知