【jvm】05-为什么你写的代码有时候和预期不一致

欢迎关注b站账号/公众号【六边形战士夏宁】,一个要把各项指标拉满的男人。该文章已在github目录收录。

屏幕前的大帅比大漂亮如果有帮助到你的话请顺手点个赞、加个收藏这对我真的很重要。别下次一定了,都不关注上哪下次一定。

1.前端编译

1.1.javac编译器

即一般所说的编译,从javac代码的总体结构来看,编译过程大致可以分为1个准备过程和3个处理过程,它们分为

1)准备过程:初始化插入式注解处理器

2)解析与填充符号表过程,构造抽象语法树

3)插入式注解处理器的注解处理过程

4)分析与字节码生成过程:语法检查->控制流分析->解析语法糖->字节码生成

语法糖主要有以下几种:泛型、自动拆装箱遍历循环、条件编译

类型擦除(编译前)

public static void main(String[] args) {
Map<String,String> map = new HashMap<String,String>(16);
map.put("name","csx-mg");
String name = map.get("name");
System.out.println(name);
}

类型擦除(编译后)

public static void main(String[] args) {
//类型擦除
Map map = new HashMap();
map.put("name", "csx-mg");
//强制转换
String name = (String)map.get("name");
System.out.println(name);
}

例如如下代码不可编译


public static void method(List<String> list){
} public static void method(List<Integer> list){ }

自动拆装箱

Integer a= 200;
Integer b = 200;
System.out.println(a==b);

输出为false

2.后端编译

2.1.即时编译器

首先主流的java虚拟机同时包含解释器与编译器,这样可以保证同时使用两者的优点。

热点代码会被编译成本地代码,主要针对方法和被多次执行的循环体,这里还会触发一个有意思的现象栈上替换

主要有两种热点代码采集方式:基于采样的热点探测、基于计数的热点探测。Hotspot采用了第二种,使用了方法调用计数器(默认10000次)和回边计数器(默认10700)

2.2.提前编译器

目的是改善java的启动时间,演变为现在所熟知的JIT

目前也在积极开发更多更优秀的提前编译器,用于匹配新出的一些垃圾回收器

2.3.编译优化

1.最重要的优化:方法内联:把目标方法的代码原封不动地“复 制”到发起调用的方法之中,避免发生真实的方法调用。

2.最前沿的优化:逃逸分析:栈上分配(对象往栈上分配)、标量替换(大对象拆成基础数据类型)、同步消除(消除无用的线程同步)

3.最经典的优化:公共子表达式消除(例如 a=1和b=1先后执行顺序并没有区别,可以先执行初始化a,然后所有用到b的地方都替换为a)

4.最显著的优化:无用代码消除

5.java经典优化:数组边界消除检查

1)数组下标是一个常量,如foo[3],只要在编译期根据数据流分析来确定foo.length的值,并判断下标“3”没有越界,执行的时候就无须判断了。

2)数组访问发生在循环之中,并且使用循环变量来进行数组的访问。如果编译器只要通过数据流分析就可以判定循环变量的取值范围永远在区间[0,foo.length)之内,那么在循环中就可以把整个数组的上下界检查消除掉。

if(foo!=null){
return foo.value;
}else{
throw new NullPointException
}

3)如果foo几乎不会发生NPE,那么上述方法无疑是浪费了一次判断性能,就会被直接优化成trycatch

其它优化策略:编译器策略、基于性能监控的优化技术、基于证据的优化技术、数据流敏感重写、语言相关的优化技术、内存及代码位置变换、循环变换、全局代码调整、控制流图变换等

参考资料

《深入理解Java虚拟机》-周志明

【jvm】05-为什么你写的代码有时候和预期不一致的更多相关文章

  1. 不写一行代码,利用常用工具和软件批量下载URL资源

    有时候会遇到这种情况:想从某个网站下载一批东西,目标URL是比较规整的,而且结构都一样(仅某些字段不同).但又懒得开IDE专门写个脚本去弄,今天就和大家分享一下,如何利用手边常用的软件和工具,不用写一 ...

  2. 朱晔的互联网架构实践心得S2E2:写业务代码最容易掉的10种坑

    我承认,本文的标题有一点标题党,特别是写业务代码,大家因为没有足够重视一些细节最容易调的坑(侧重Java,当然,本文说的这些点很多是不限制于语言的). 1.客户端的使用 我们在使用Redis.Elas ...

  3. 使用 TypeScript & mocha & chai 写测试代码实战(17 个视频)

    使用 TypeScript & mocha & chai 写测试代码实战(17 个视频) 使用 TypeScript & mocha & chai 写测试代码实战 #1 ...

  4. .net学习之Session、Cookie、手写Ajax代码以及请求流程

    1.IIS 7 以上版本集成了两种模式,一种是经典模式,一种是集成模式(直接将asp.net框架集成到IIS中) 2.浏览器和服务器端通过什么技术来实现的?Socket(套接字),通信的语法是HTTP ...

  5. jQuery之父:每天都写点代码

    去年秋天,我的“兼职编程项目”遇到了一些问题:要不是从 Khan Academy 的项目里挪出时间来的话,我根本没办法将不理想的进度弥补上. 这些项目遇到了一些严重的问题.之前的工作我主要是在周末,有 ...

  6. Wix#可以直接写C#代码来生成Wix的MSI安装文

    博客搬到了fresky.github.io - Dawei XU,请各位看官挪步.最新的一篇是:Wix#可以直接写C#代码来生成Wix的MSI安装文.

  7. 关于 OnCloseQuery: 顺序、不能关机等(所有的windows的广播消息都是逐窗口传递的)——如果一个窗体的OnCloseQuery事件中如果写了代码那么WM_QUERYENDSESSION消息就传不过去了msg.result会返回0,关机事件也就停止了

    系统关闭窗体的事件顺序为: OnCloseQuery ----> OnClose ----> OnDestroy 下面的代码说明问题: unit Unit3; interface uses ...

  8. Lombok : 让你写 Java代码像C#一样爽

    前言 我曾经是一名 .Net 开发,如今的我是一名 Java 开发者.在我享受着 Java 成熟的生态时,我常常怀念 c# 简洁的语法:自动属性.类型推断.自动初始化器 .... 鱼,我所欲也,熊掌亦 ...

  9. 开箱即用(out-of-box)的Redis序列号生成器,不用再写任何代码,你值得拥有

      先看整体效果 把简单的东西“傻瓜化”是软件开发追求的目标之一.请看下图: 左边是在 application.yml 里配置了3个生成器,右边可以直接注入到代码中使用,注意,不用写任何代码.这酸爽. ...

随机推荐

  1. 理解JMX之介绍和简单使用

    JMX最常见的场景是监控Java程序的基本信息和运行情况,任何Java程序都可以开启JMX,然后使用JConsole或Visual VM进行预览.下图是使用Jconsle通过JMX查看Java程序的运 ...

  2. 关系型数据库和非关系型数据库区别、oracle与mysql的区别

    一.关系型数据库 关系型数据库,是指采用了关系模型来组织数据的数据库.    关系模型是在1970年由IBM的研究员E.F.Codd博士首先提出的,在之后的几十年中,关系模型的概念得到了充分的发展并逐 ...

  3. 【Linux】【Services】【Docker】网络

    容器的网络模型: closed container: 仅有一个接口:loopback 不参与网络通信,仅适用于无须网络通信的应用场景,例如备份.程序调试等: --net none bridged co ...

  4. 【力扣】973. 最接近原点的 K 个点

    我们有一个由平面上的点组成的列表 points.需要从中找出 K 个距离原点 (0, 0) 最近的点. (这里,平面上两点之间的距离是欧几里德距离.) 你可以按任何顺序返回答案.除了点坐标的顺序之外, ...

  5. 【Spark】【复习】Spark入门考前概念相关题复习

    Spark考前概念相关题复习 AUthor:萌狼蓝天 哔哩哔哩:萌狼蓝天 博客园:我的文章 - 萌狼蓝天 博客:萌狼工作室 - 萌狼蓝天 (mllt.cc) 选择题 Hadoop 1.HADOOP的三 ...

  6. Laravel框架角色、权限

    角色表结构如下: 权限表结构如下: 控制器代码: //递归查询权限列表 public function index(){ $data = ManagePermissionModel::query()- ...

  7. Nginx区分搜索引擎

    目录 一.简介 二.配置 一.简介 场景: 当从百度点进来显示中文页面,而谷歌显示英文界面. 原理: 根据referer头来判断 二.配置 这样配置以后,凡是从百度或者google点过来的请求都会跳转 ...

  8. HTTP隧道解决的问题

    转自别人的文章:https://blog.csdn.net/gogzf/article/details/78385506 客户端通常会用 Web 代理服务器代表它们来访问 Web 服务器.比如,很多公 ...

  9. Charles ios设备抓包

    在Mac下做开发,用Fiddler抓包由于离不开Windows比较痛苦,还好有Charles,到官网http://www.charlesproxy.com/可下载到最新版本(若不支持rMBP可拖到Re ...

  10. Position定位详解

    Position CSS position属性用于指定一个元素在文档中的定位方式.top,right,bottom 和 left 属性则决定了该元素的最终位置. 在分析position元素定位之前,先 ...