当前位置:首页 > 科技  > 软件

微博二面:所有对象都一定被分配在堆中么?

来源: 责编: 时间:2023-10-27 09:14:45 383观看
导读什么是逃逸分析所谓逃逸,包括方法逃逸和线程逃逸,线程逃逸的逃逸程度高于方法逃逸(线程逃逸 > 方法逃逸):当一个对象在方法里面被定义后,它如果被外部方法所引用(例如作为调用参数传递到其他方法中),这种称为方法逃逸;可能被外

什么是逃逸分析

所谓逃逸,包括方法逃逸和线程逃逸,线程逃逸的逃逸程度高于方法逃逸(线程逃逸 > 方法逃逸):rlc28资讯网——每日最新资讯28at.com

当一个对象在方法里面被定义后,它如果被外部方法所引用(例如作为调用参数传递到其他方法中),这种称为方法逃逸;rlc28资讯网——每日最新资讯28at.com

可能被外部其他线程访问到,譬如赋值给可以在其他线程中访问的实例变量,这种称为线程逃逸;rlc28资讯网——每日最新资讯28at.com

this 引用逃逸就是一种线程逃逸:在构造器构造还未彻底完成前(即实例初始化阶段还未完成),将自身 this 引用向外抛出并被其他线程复制(访问)了该引用,那么其他线程就可能会访问到该还未被初始化的变量。rlc28资讯网——每日最新资讯28at.com

举个例子:rlc28资讯网——每日最新资讯28at.com

public class FinalReferenceEscapeTest {     final int i;     static FinalReferenceEscapeTest obj;     public FinalReferenceEscapeTest () {          i = 1;                   // 1. 写 final 域  obj = this;              // 2. this 引用在此 "逸出" } // 线程 A public static void writer() {   new FinalReferenceEscapeExample();  } // 线程  B public static void reader() {   if (obj != null) {      // 3    int temp = obj.i;   // 4   }  }}

假设一个线程 A 执行 writer() 方法,另一个线程 B 执行 reader() 方法。这里的操作 2 将自身 this 引用向外抛出,使得 FinalReferenceEscapeTest 对象还未完成构造前就为其他线程可见。rlc28资讯网——每日最新资讯28at.com

有的同学可能会问,这个操作 2 不是在构造函数的最后一步吗,它执行完构造函数也执行完了,对象不就已经完成构造了吗?rlc28资讯网——每日最新资讯28at.com

But 这里的操作 1 和操作 2 之间可能被重排序。如下图所示,线程 B 不能正确地读到 i = 1,而是未初始化的 i = 0:rlc28资讯网——每日最新资讯28at.com

所以,我们可以得出这样的结论:在构造函数返回前,被构造对象的引用不能为其他线程所见,因为此时的各个字段(域)可能还没有被初始化。rlc28资讯网——每日最新资讯28at.com

如果虚拟机能够确定一个对象不会发生方法逃逸和线程逃逸,或者逃逸程度比较低(只发生方法逃逸,不发生线程逃逸),则(JIT 即时编译器)可以为这个对象实例采取不同程度的优化,比如锁消除 Lock Elimination(也称为 “同步消除 Synchronization Elimination”)、还有 栈上分配(Stack Allocations) 和 标量替换(Scalar Replacement)等rlc28资讯网——每日最新资讯28at.com

栈上分配

栈上分配(Stack Allocations)是 JIT 即时编译器的一项优化技术:如果确定一个对象不会逃逸出线程之外(不发生逃逸或逃逸程度较低 - 方法逃逸),那让这个对象在栈(线程私有)上分配内存将会是一个很不错的主意,对象所占用的内存空间就可以随栈帧出栈而销毁。rlc28资讯网——每日最新资讯28at.com

在一般应用中,完全不会逃逸的局部对象和不会逃逸出线程的对象所占的比例是很大的,如果能使用栈上分配,那大量的对象就会随着方法的结束而自动销毁了,垃圾收集子系统的压力将会下降很多rlc28资讯网——每日最新资讯28at.com

示例代码:rlc28资讯网——每日最新资讯28at.com

public class StackAllocationExample {    private static final int MAX = 10000000;        public static void main(String[] args) {        long start = System.currentTimeMillis();        for (int i = 0; i < MAX; i++) {            allocateOnStack();        }        long end = System.currentTimeMillis();        System.out.println("Time taken: " + (end - start) + "ms");    }        private static void allocateOnStack() {        Point p = new Point();        p.x = 1;        p.y = 2;    }        private static class Point {        int x;        int y;    }}

在这个示例代码中,我们定义了一个私有的静态内部类 Point,它包含两个 int 类型的成员变量 x 和 y。在 main 方法中,我们循环调用 allocateOnStack 方法,该方法内部创建一个 Point 对象并将其成员变量赋值为 1 和 2。由于 allocateOnStack 方法没有返回 Point 对象,换言之 Point 对象是不会被暴露给其他线程的,即不会发生线程逃逸,因此编译器可以将该对象分配在栈上而不是堆上。rlc28资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-15315-0.html微博二面:所有对象都一定被分配在堆中么?

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: DFA算法,高效实现敏感词检测与替换!

下一篇: Python字典全解析:从基础到高级应用

标签:
  • 热门焦点
  • 中兴AX5400Pro+上手体验:再升级 双2.5G网口+USB 3.0这次全都有

    2021年11月的时候,中兴先后发布了两款路由器产品,中兴AX5400和中兴AX5400 Pro,从产品命名上就不难看出这是隶属于同一系列的,但在外观设计上这两款产品可以说是完全没一点关系
  • 女孩租房开2小时空调用完100元电费引热议:5级能耗惹不起 月薪过万电费也交不起

    近日,江苏苏州一女孩租房当天充值了100元电费,开着空调不到2小时发现电费已用完。对于为什么这个快,房东表示,电表坏了这种情况很多,之前也遇到过,给租客换
  • 共享单车的故事讲到哪了?

    来源丨海克财经与共享充电宝相差不多,共享单车已很久没有被国内热点新闻关照到了。除了一再涨价和用户直呼用不起了。近日多家媒体再发报道称,成都、天津、郑州等地多个共享单
  • 10天营收超1亿美元,《星铁》比《原神》差在哪?

    来源:伯虎财经作者:陈平安即便你没玩过《原神》,你一定听说过的它的大名。恨它的人把《原神》开服那天称作是中国游戏史上最黑暗的一天,有粉丝因为索尼在PS平台上线《原神》,怒而
  • 大厂卷向扁平化

    来源:新熵作者丨南枝 编辑丨月见大厂职级不香了。俗话说,兵无常势,水无常形,互联网企业调整职级体系并不稀奇。7月13日,淘宝天猫集团启动了近年来最大的人力制度改革,目前已形成一
  • 冯提莫签约抖音公会 前“斗鱼一姐”消失在直播间

    来源:直播观察提起&ldquo;冯提莫&rdquo;这个名字,很多网友或许听过,但应该不记得她是哪位主播了。其实,作为曾经的&ldquo;斗鱼一姐&rdquo;,冯提莫在游戏直播的年代影响力不输于现
  • 2纳米决战2025

    集微网报道 从三强争霸到四雄逐鹿,2nm的厮杀声已然隐约传来。无论是老牌劲旅台积电、三星,还是誓言重回先进制程领先地位的英特尔,甚至初成立不久的新
  • iQOO Neo8系列今日官宣:首发天玑9200+ 全球安卓最强芯!

    在昨日举行的的联发科新一代旗舰芯片天玑9200+的发布会上,iQOO官方也正式宣布,全新的iQOO Neo8系列新品将全球首发搭载这款当前性能最强大的移动平台
  • 北京:科技教育体验基地开始登记

      北京“科技馆之城”科技教育体验基地登记和认证工作日前启动。首批北京科技教育体验基地拟于2023年全国科普日期间挂牌,后续还将开展常态化登记。  北京科技教育体验基
Top