堆是分配对象存储的唯一选择吗?

随着JIT编译器的发展与逃逸分析逐渐成熟,栈上分配、标量替换优化技术将会导致一些微妙的变化,所以对象都分配到堆上也渐渐变得不是那么绝对了。

在Java虚拟机中,对象是在Java堆中分配内存的,这是一个普遍的常识。但是,有一种特殊情况,那就是如果经过逃逸分析后发现,一个对象并没有逃逸出方法的话,那么就可能被优化成栈上分配。这样就无需在堆上分配内存,也无须进行垃圾回收。这也是最常见的堆外存储技术。

如何将堆上的对象分配到栈,需要使用逃逸分析手段。Java jdk u6u23版本之后是默认开启逃逸分析的。

这是一种可以有效减少Java程序中同步负载和内存堆分配压力的跨函数全局数据流分析算法。

通过逃逸分析,Java HotSpot 编译器能够分析出一个新的对象的引用的使用范围从而决定是否要将这个对象分配到堆上。

结论:开发中能使用局部变量的,就不要使用在方法外定义。

1、逃逸分析:代码优化–栈上分配

JIT编译器在编译期间根据逃逸分析的结果,发现如果一个对象没有逃逸出方法的话,就可能被优化成栈上分配。分配完成后,继续在调用栈内执行,最后线程结束,栈空间被回收,局部变量对象也被回收,这样就无须进行垃圾回收了。但是注意的是,Oracle HotSpot JVM并没有这么做。

2、逃逸分析:代码优化–同步省略

线程同步的代价是相当高的,同步的后果是降低并发性和性能。

在动态编译同步块的时候,JIT编译器可以借助逃逸分析来判断同步块所使用的锁对象是否只是能够被一个线程访问而没有被发布到其他的线程。如果没有,那么JIT编译器在编译这个同步块的时候就会取消对这部分代码的同步,这样就能大大提高并发性个性能。这个取消同步的过程就叫同步省略,也叫锁消除。

3、逃逸分析:代码优化–标量替换(或者分离对象)

有的对象可能不需要作为一个连续的内存结构存在也可以被访问到,那么对象的部分(或全部)可以不存储在内存,而是存储在CPU寄存器中。

标量:是指一个无法再分解成更小的数据的数据。Java中的元数据类型就是标量。相对的,那些还可以分解的数据叫做聚合量。

在JIT编译阶段,如果经过逃逸分析,发现一个对象不会被外界访问的话,那么经过JIT优化,会把这个对象拆分成若干个成员变量来代替,这个过程就是标量替换。

说明:jdk1.7之后JIT逃逸分析是默认打开的(Server模式下),也就是以上这三种优化JVM就可以帮你做了。

这项技术还不是很成熟,因为进行逃逸分析本身就要耗费资源,逃逸分析后发现无对象没有逃逸在这种最坏情况更是耗费资源,还费力不讨好,但是这项技术也是值得我们去关注的。Oracle HotSpot JVM主要实现标量替换,并没有去使用栈上分配。就像栈顶缓存技术一样也只是个概念。其实Java还是偏向把对象放在堆上进行存储的,jdk1.7以后就把字符串常量池移到堆上。那到底堆是不是唯一存放对象的选择呢?用你敏捷的逻辑去推断思考吧!

有用点个关注,手留余香!

逃逸分析--代码三大优化策略(堆不是分配对象存储的唯一选择)相关推荐

  1. oom机制分析及对应优化策略

    转载自https://blog.51cto.com/12814931/2343623 近日接了一些oom案子,此类问题通常是客户自身业务导致的问题.但现在客户的提问越来越复杂,通常情况下我们需要站在客 ...

  2. JVM【带着问题去学习 01】什么是JVM+内存结构+堆内存+堆内存参数(逃逸分析)

    1.是什么 (1) 基本概念:可运行 Java 代码的非真实计算机 ,包括一套字节码指令集.一组寄存器.一个栈.一个垃圾回器,堆和一个存储方法域.它运行在操作系统之上,与硬件没有直接的交互. (2) ...

  3. 逃逸分析和标量替换技术,你明白了吗

    文章目录 逃逸分析 怎么做逃逸分析后的优化? 什么是线程分配缓冲TLAB? 什么是标量替换? 实战 开始逃逸分析(默认开启的) 关闭逃逸分析-XX:-DoEscapeAnalysis 逃逸分析 逃逸分 ...

  4. JVM学习笔记之-堆,年轻代与老年代,对象分配过程,Minor GC、Major GC、Full GC,堆内存大小与OOM,堆空间分代,内存分配策略,对象分配内存,小结堆空间,逃逸分析,常用调优工具

    堆的核心概述 概述 一个JVM实例只存在一个堆内存,堆也是Java内存管理的核心区域.Java堆区在JVM 启动的时候即被创建,其空间大小也就确定了.是JVM管理的最大一块内存空间. 堆内存的大小是可 ...

  5. 3.内存分配、逃逸分析与栈上分配、直接内存和运行时常量池、基本类型的包装类和常量池、TLAB、可达性分析算法(学习笔记)

    3.JVM内存分配 3.1.内存分配概述 3.2.内存分配–Eden区域 3.3.内存分配–大对象直接进老年代 3.3.1.背景 3.3.2.解析 3.4.内存分配–长期存活的对象进去老年代 3.5. ...

  6. 通过实例理解 Go 逃逸分析

    本文转载自白明老师,这是中文社区里面最好.最全面的一篇关于逃逸分析的文章,写得非常好.既有理论.又有实践,引经据典,精彩至及. 翻看了一下自己的Go文章归档[1],发现自己从未专门写过有关Go逃逸分析 ...

  7. 通过实例理解Go逃逸分析

    翻看了一下自己的Go文章归档[1],发现自己从未专门写过有关Go逃逸分析(escape analysis)的文章.关于Go变量的逃逸分析,大多数Gopher其实并不用关心,甚至可以无视.但是如果你将G ...

  8. GC分类、TLAB、逃逸分析、栈上分配、同步消除、标量替换

    GC分类 JVM的调优的一个环节,也就是垃圾收集,我们需要尽量的避免垃圾回收,因为在垃圾回收的过程中,容易出现STW(Stop the World)的问题,而 Major GC 和 Full GC出现 ...

  9. Golang 内存分配与逃逸分析

    参考:灵魂拷问:Go 语言这个变量到底分配到哪里了? 来源于 公众号: 脑子进煎鱼了 ,作者陈煎鱼. 我们在写代码的时候,有时候会想这个变量到底分配到哪里了?这时候可能会有人说,在栈上,在堆上.信我准 ...

最新文章

  1. html三列布局中间固定,常见的三列布局(左右固定宽度,中间自适应)
  2. (一)为什么你应该(从现在开始就)写博客
  3. NodeJS学习日记--VSCode下调试
  4. 十六进制转double
  5. REST面向资源架构 RESTful架构
  6. 常见web漏洞验证攻略(萌新入坑必备!)
  7. 系统微服务签发token
  8. ER图转换成关系模式集的规则
  9. 使用Maven编译项目遇到——“maven编码gbk的不可映射字符”解决办法 ——转载...
  10. UIView的Touch事件UIControlEvents详解
  11. 百度广告场景大数据治理应用实践
  12. 多线多IP的服务器配置
  13. java单例设计及其在jdk中的应用
  14. 吾很努力了,吾不是关键因素
  15. 【边喝caffee边Caffe 】(三) Check failed: registry.count(t ype) == 1 (0 vs. 1) Unknown layer type
  16. YARN动态资源池配置案例
  17. 01—C语言基本语句
  18. Android版的股票行情K线图开发
  19. java多数据库开发evn,Java,在多线程evnironments中通过散列统一划分传入的工作
  20. 你或许也想拥有专属于自己的AI模型文件格式(推理部署篇)-(8)

热门文章

  1. cobol 文件相关语句
  2. 支持ImageX图像处理的WordPress插件推荐-WPJAM插件
  3. 【cs231n】图像分类-Linear Classification线性分类
  4. 好用的图片浏览器——ArcSoft Photo+
  5. 2021年教师资格证面试试讲稿:小学英语 Welcome to Africa
  6. 全球中文论坛百强排行榜完全名单
  7. Mindmanager2019官方中文版
  8. mysql的join三种算法_MySQL系列(九)---MySQL几种JOIN算法
  9. 10010---PMP--例外管理
  10. 联邦学习【FATE安装与部署】