String源码中的"avoid getfield opcode"
引言:
之前一篇文章梳理了String的不变性原则,还提到了一段源码中注释"avoid getfield opcode",当时通过查阅资料发现,这是为了防止 getfield(获取指定类的实例域,并将其值压入到栈顶)这个操作码的执行,这篇文章想从字节码的角度去分析一下。
先看一段代码吧
/**
* Created by chenqimiao on 16/11/29.
*/
public class Main { public char[] chars = new char[10]; public void test() {
System.out.println(chars[0]);
System.out.println(chars[1]);
System.out.println(chars[2]);
} public static void main(String args[]) {
Main m = new Main();
m.test();
}
}
执行 javap -c Main ,分析一下字节码,查看一下分析后生成的操作码:

查阅"深入理解JVM虚拟机"一书中的虚拟机字节码指令表,试着分析一下test方法下面的code.
4.获取指定的实例域,并将其值压入栈顶
7.将int型0推送至栈顶
8.将char数组指定索引的值推至栈顶
9.调用实例方法
总结一下的话,就是每次获取实例域 推到栈顶,然后推被操作的索引到栈顶,然后取到对应数组的指定索引的值推到栈顶,然后就是调用输出方法了。可以看到输出三次,getfield操作码就调用了三次,假想我们在遍历这个char数组,那象上述写法,要频繁调用getfield操作码了。
我们学一下String源码中的写法,可能能改善一下这个问题。
/**
* Created by chenqimiao on 16/11/29.
*/
public class Main { public char[] chars = new char[10]; public void test() {
char[] chars = this.chars;
System.out.println(chars[0]);
System.out.println(chars[1]);
System.out.println(chars[2]);
} public static void main(String args[]) {
Main m = new Main();
m.test();
}
}
执行 javap -c Main ,分析一下字节码,查看一下分析后生成的操作码:

好了,我把实例变量的数组的引用赋给了一个局部引用了。
我们还是分析一下test方法中的code把
0.将第一个引用类型本地变量推送至栈顶(就是将局部变量引用chars放到栈顶)
1.获取实例域的引用推到栈顶(实例变量的成员chars放到栈顶)
4.将栈顶顶引用类型数值存入指定本地变量(就是把成员变量chars的引用给到局部变量的引用chars,这里是引用值拷贝,不是引用指向内存的值的拷贝)
5.获取指定的实例域,并将其值压入栈顶
8.将第二个引用类型本地变量推送至栈顶
9.将int型0推到栈顶
10.将char数组指定的索引的值压入到栈顶
11.调用实例方法(输出)
在14-20的过程中没有再发生"getfield"操作,而是用aload_1操作码将第二个本地引用(被赋值后的本地引用chars)推至栈顶,就可以执行接下来的一系列操作。
到这里的话"avoid getfield opcode"的意思已经非常清楚明了,在遍历实例的char数组的时候,将实例数组的引用赋值给一个本地引用,不需要频繁调用操作用码"getfield",只需要在第一次对本地引用赋值的时候,调用一次getfield,接下来的遍历取值的时候,只需要将本地引用压入到栈顶。
String源码中的"avoid getfield opcode"的更多相关文章
- String源码中hashCode算法
针对java中String源码hashcode算法源码分析 /** The value is used for character storage. */ private final char val ...
- java面试之String源码中equals具体实现
废话不多说,直接看代码,注释已经写在上面了: public boolean equals(Object anObject) { if (this == anObject) {//比较两个对象的地址 r ...
- 程序兵法:Java String 源码的排序算法(一)
摘要: 原创出处 https://www.bysocket.com 「公众号:泥瓦匠BYSocket 」欢迎关注和转载,保留摘要,谢谢! 这是泥瓦匠的第103篇原创 <程序兵法:Java Str ...
- JDK代码中的优化 之 “avoid getfield opcode”
在查看String类源码时,常看到注释 /* avoid getfield opcode */ 如 trim()方法 public String trim() { int len = value.le ...
- (转)Java中的String为什么是不可变的? -- String源码分析
背景:被问到很基础的知识点 string 自己答的很模糊 Java中的String为什么是不可变的? -- String源码分析 ps:最好去阅读原文 Java中的String为什么是不可变的 什 ...
- java基础进阶一:String源码和String常量池
作者:NiceCui 本文谢绝转载,如需转载需征得作者本人同意,谢谢. 本文链接:http://www.cnblogs.com/NiceCui/p/8046564.html 邮箱:moyi@moyib ...
- 基于JDK1.8的String源码学习笔记
String,可能是学习Java一上来就学习的,经常用,但是却往往只是一知半解,甚至API有时也得现查.所以还是老规矩,倒腾源码. 一.java doc 这次首先关注String的doc,因为其实作为 ...
- Java基础(八)--String(源码)、StringBuffer、StringBuilder
String源码:基于jdk1.8 public final class String implements Serializable, Comparable<String>, CharS ...
- 死啃了String源码之后
Java源码之String 说在前面: 为什么看源码: 最好的学习的方式就是模仿,接下来才是创造.而源码就是我们最好的模仿对象,因为写源码的人都不是一般的人,所以用心学习源码,也就可能变成牛逼的人.其 ...
随机推荐
- 前端神器avalonJS入门(三)
本章将介绍如何使用avalon来实现前端路由功能. 我们需要用到两个avalon路由配套模块—— mmHistory.js 和 mmRouter.js .其中mmHistory是用于历史管理,它会劫持 ...
- (DNS被劫持所导致的)QQ音乐与视频网页打开很慢的解决方法
这周开始发现一个很让人抓狂的现象,QQ音乐网页(http://y.qq.com)与QQ视频(http://v.qq.com/)网页打开超慢,甚至是无法打开,严重影响了业余的音乐视频生活. 以QQ视频为 ...
- JS、JQuery和ExtJs的跨域处理
1.什么是跨域?跨域,JavaScript出于安全方面的考虑,不允许跨域调用其他页面的对象.简单地理解就是因为JavaScript同源策略的限制,a.com 域名下的js无法操作b.com或是c.a. ...
- spring-boot 和 docker 集成
描述 java 的 Spring是一个很火的框架,Spring boot 这个也不用说了,Docker 近年也很火热, 本文就介绍下我在 Spring boot + Docker的集成一些经验 :) ...
- Mac 软件篇
对于美好事务的追求无论何时都不算晚. ** 文章内容来着我整理的fetool,以下内容可能更新不及时 ** Mac 下的软件那么多,又是免费又是付费,应该怎么选呢?我来分享下我的推荐列表,推荐的优先级 ...
- Windows Azure Storage (21) 使用AzCopy工具,加快Azure Storage传输速度
<Windows Azure Platform 系列文章目录> Update 2016-09-28 想要在Azure云端,使用AzCopy工具,从Azure China 上海数据中心存储账 ...
- spring事务管理器设计思想(一)
在最近做的一个项目里面,涉及到多数据源的操作,比较特殊的是,这多个数据库的表结构完全相同,由于我们使用的ibatis框架作为持久化层,为了防止每一个数据源都配置一套规则,所以重新实现了数据源,根据线程 ...
- Atitit 数据库的事件机制--触发器与定时任务attilax总结
Atitit 数据库的事件机制--触发器与定时任务attilax总结 1.1. 事件机制的图谱1 2. 触发器的类型2 3. 实现原理 After触发器 Vs Instead Of触发器2 3.1. ...
- JQuery图片切换动画效果
由于博主我懒,所以页面画的比较粗糙,但是没关系,因为我主要讲的是如何实现图片动画切换. 思路:想必大家都逛过淘宝或者其他的一些网站,一般都会有图片动画切换的效果,那是怎样实现的呢?博主我呢,技术不是很 ...
- iOS--通讯录、蓝牙、内购、GameCenter、iCloud、Passbook等系统服务开发汇总
iOS开发过程中有时候难免会使用iOS内置的一些应用软件和服务,例如QQ通讯录.微信电话本会使用iOS的通讯录,一些第三方软件会在应用内发送短信等.今天将和大家一起学习如何使用系统应用.使用系统服务: ...