Android学习笔记 手动执行Java字节码

Android学习笔记 手动执行Java字节码

@[Android, 字节码]

背景

这一次是玩安卓知识星球的第二期作业(分析每一行字节码执行过程中的本地变量数组和操作数栈的状态),完成第一期作业的过程中需要需要操作字节码,但借助Javassist的帮助也没有去学习字节码的相关知识,现在不得不好好的看看Java的字节码究竟是怎样执行的。

JVM的内存模型

首先复习一下JVM的内存模型 ,JVM的内存模型分为几个区域,如下图:


JVM的内存模型.jpg
  • 程序计数器:这是线程私有的数据区,用来表示当前执行的是哪一行的指令
  • 虚拟机栈:一个栈结构,存储的元素被称为栈帧,每个栈帧包含了一个方法的数据和部分过程结果的区域,同时包含动态连接的信息和方法返回值
    • 局部变量表:用来保存方法局部变量的数组结构
    • 操作数栈:JVM是基于栈结构,操作数栈就是具体用辅助执行指令的栈,栈深度在编译期就写入到class文件中
    • 动态链接:作用是将对方法符号引用转换为直接引用
    • 返回地址:方法执行完成后返回的位置,即调用自己的位置
  • 本地方法栈:跟虚拟机栈类似的为本地方法服务的栈结构
  • 方法区:线程共享的区域,存储运行时常量池,方法的字节码数据,类的字段等
  • 堆:也是线程共享的区域,存储的是Java动态生成的对象数据,垃圾回收器管理的也是这的区域

class文件

对JVM内存模型有了个简单的回顾,我们继续看看class文件的结构是怎么样的。


1986868-5b44e95ff7e30847.jpeg
  1. 魔数和版本号都是对文件本身的描述
  2. 常量池:存储的是字面量和符号引用,除了对一些基本类型的操作,像是类名、方法名、常量等都在这里有定义
  3. 访问标记:标记class是表示一个类还是一个接口,是否公开,是否是abstract等信息
  4. 类索引:引用常量池中的类的全限定类名
  5. 父类索引:引用常量池中的父类的全限定类名
  6. 接口索引:接口数量和引用常量池中的接口的全限定接口名
  7. 字段表集合:定义类所有字段的各种属性
  8. 方法:包含每个方法的各种属性,其中就包括上面说到的操作数栈的深度
  9. 属性:定义了class文件的属性,比如源代码文件名

手动执行字节码指令

接下来结合代码,我们来手动执行字节码指令:

public class Hello {
    public static void main(String[] args) {
        int a = 1;
        int b = 10;
        String c = "abc";
        System.out.println(a + b + c + get3());
    }

    private static int get3() {
        int result = 0;
        for (int i = 0; i < 3; i++) {
            result ++;
        }
        return result;
    }
}

// 生成的字节码指令
// main()
 0 iconst_1
 1 istore_1
 2 bipush 10
 4 istore_2
 5 ldc #2 <abc>
 7 astore_3
 8 getstatic #3 <java/lang/System.out>
11 new #4 <java/lang/StringBuilder>
14 dup
15 invokespecial #5 <java/lang/StringBuilder.<init>>
18 iload_1
19 iload_2
20 iadd
21 invokevirtual #6 <java/lang/StringBuilder.append>
24 aload_3
25 invokevirtual #7 <java/lang/StringBuilder.append>
28 invokestatic #8 <com/zhixiao/readclass/Hello.get3>
31 invokevirtual #6 <java/lang/StringBuilder.append>
34 invokevirtual #9 <java/lang/StringBuilder.toString>
37 invokevirtual #10 <java/io/PrintStream.println>
40 return

// get3()
 0 iconst_0
 1 istore_0
 2 iconst_0
 3 istore_1
 4 iload_1
 5 iconst_3
 6 if_icmpge 18 (+12)
 9 iinc 0 by 1
12 iinc 1 by 1
15 goto 4 (-11)
18 iload_0
19 ireturn

代码很简单,我们先来看以下各部分在虚拟机中的存储情况


Java字节码总览 | center

代码加载到方法区,正在被执行的方法作为栈帧被初始化到虚拟机栈,执行第一条指令,常量1被压入栈


1576237431800.png

new对象时,在堆生成该对象,并将对象的地址压入栈
1576237550745.png

执行方法时,调用方法生成新的栈帧并压入虚拟机栈,然后将返回值设为方法调用处的下一条指令


1576237607977.png

退出方法时从返回地址返回,如果有返回值则将栈顶的值压入调用处的操作数栈
1576237726715.png

以上只是部分分析过程,具体可以下载我做的ppt查看全部的过程会更清楚
class执行过程.gif

ppt的地址:

链接:https://pan.baidu.com/s/11SDZbSAiiEGtlg5wZi1ztw
提取码:np8f

总结

将学习的结果写出来真的花时间花精力,但是我相信通过这样的方式我会对所学的内容理解更加深刻。现在希望能继续坚持下去。可以参考项目地址

参考:

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,736评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,167评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,442评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,902评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,302评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,573评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,847评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,562评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,260评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,531评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,021评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,367评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,016评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,068评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,827评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,610评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,514评论 2 269

推荐阅读更多精彩内容