zoukankan      html  css  js  c++  java
  • Java中的栈上分配

    博客搬家自https://my.oschina.net/itsyizu/blog/

    什么是栈上分配

    栈上分配是java虚拟机提供的一种优化技术,基本思想是对于那些线程私有的对象(指的是不可能被其他线程访问的对象),可以将它们打散分配在栈上,而不是分配在堆上。分配在栈上的好处是可以在函数调用结束后自行销毁,而不需要垃圾回收器的介入,从而提供系统的性能。

    栈上分配的一个技术基础是进行逃逸分析。逃逸分析的目的是判断对象的作用域是否有可能逃逸出函数体。

    下面的代码显示了一个逃逸的对象:

    public class PartionOnStack {
       static class User{
        private int id;
        private String name;
        public User(){}
           }
        private static  User user;
        public static void foo() {
        user=new User();
        user.id=1;
        user.name="sixtrees";
        }
        public static void main(String[] args) {
        foo();
        }
    
    }

    因为上面的代码中的User的作用域是整个Main Class,所以user对象是可以逃逸出函数体的。下面的代码展示的则是一个不能逃逸的代码段。

    public class PartionOnStack {
        class User{
        private int id;
        private String name;
        public User(){}
           }
        public  void foo() {
        User user=new User();
        user.id=1;
        user.name="sixtrees";
        }
        public static void main(String[] args) {
        PartionOnStack pos=new PartionOnStack();
        pos.foo();
        }
    
    }

    代码来帮忙

    通过上面的分析,我们知道java虚拟机会帮助我们在栈上进行分配,我们设置了1亿次alloc的对象创建,每个User对象实例需要占用16字节的空间,如果没有优化,累计的空间申请将有1.5GB这么大,如果我们的堆空间设置的值小于1.5GB的话,就会发生GC。代码如下:

    public class PartionOnStack {
        class User{
        public int id;
        public String name;
           }
        public  void foo() {
        User user=new User();
        user.id=1;
        user.name="sixtrees";
        }
        public static void main(String[] args) {
        System.out.println("start-----------");
        long beginTime=System.currentTimeMillis();
        PartionOnStack pos=new PartionOnStack();
        for(int i=0;i<100000000;i++)
        {     
            pos.foo();
        }
        long endTime=System.currentTimeMillis();
        System.out.println("总共运行----"+(endTime-beginTime)+"ms");
        }
    
    }

    使用下面的参数运行上面的代码

    -server -XMX10m -Xms10m -XX:+DoEscapeAnalysis -XX:+PrintGC -XX:-UseTLAB -XX:+EliminateAllocations

    运行的结果如下所示:

    image

    对于大量的零散小对象,栈上分配提供了一种很好的对象分配策略,栈上分配的速度快,并且可以有效地避免垃圾回收带来的负面的影响,但由于和堆空间相比,栈空间比较小,因此对于大对象无法也不适合在栈上进行分配。

  • 相关阅读:
    JVM内存的划分
    劝学
    java中switch的用法
    方法传递参数的分类
    ajax缓存机制
    vuex
    keep-alive
    路由滚动行为scrollBehavior
    vue等
    防止刷新路由后参数消失
  • 原文地址:https://www.cnblogs.com/shugen/p/6862981.html
Copyright © 2011-2022 走看看