zoukankan      html  css  js  c++  java
  • 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:
     
     说明栈上分配依赖逃逸分析和标量替换的实现
    对于大量的零散小对象,栈上分配提供了一种很好的对象分配优化策略,栈上分配速度快,并且可以有效避免垃圾回收带来的负面影响
    但由于和堆空间相比,栈空间较小,因此对于大对象无法也不适合在栈上分配

  • 相关阅读:
    web端ip定位
    【树状数组2】洛谷P3368
    【树状数组1】 洛谷P3374
    【割点】洛谷P3388
    【二分图匹配】洛谷P3386
    洛谷P4145 上帝造题的七分钟2 / 花神游历各国
    【线段树2】洛谷P3373
    【线段树1】洛谷P3372
    【乘法逆元】洛谷P3811
    【LCA】洛谷P3379
  • 原文地址:https://www.cnblogs.com/xxdfly/p/6652410.html
Copyright © 2011-2022 走看看