理解Android虚拟机dex指令

文章探讨了Android应用中内存结构和DEX指令的关系,通过实例展示了CPU如何通过高速缓存操作堆区数据。同时,解释了DCL(双重检查锁定)单例模式下为何需要使用volatile关键字,以防止指令重排导致的问题。
摘要由CSDN通过智能技术生成

前言

内存结构
内存结构
CPU不可以直接操作堆区数据,需要通过中间高速缓存区进行相关数据操作;

dex指令理解

我们知道Android虚拟机执行的是dex指令,我们可以先使用javac指令编译class,再通过dx指令编译查看对应java方法的dex指令;

  1. 局部变量方法调用dex指令查看;
public class Person {
    public void run() {
        Person  person = new Person();
        person.run();
    }
}

编译成Person.class文件后,使用dx --dex --verbose --dump-to=a.txt --dump-method=Person.run --verbose-dump Person.class dx指令编译Person.run方法,删除无用信息后,得到文件内容以及解释如下:

Person.run:()V:
regs: 0002; ins: 0001; outs: 0001
  0000: new-instance v0, Person //  1.在高速缓存中声明一个v0;2.将Person.class加载到方法区;3.在堆区实例化一个对象person;4.v0指向堆区的person对象;
  0002: invoke-direct {v0}, Person.<init>:()V // 调用构造方法初始化person对象,并将返回值赋给v0
  0005: invoke-virtual {v0}, Person.run:()V // 调用v0执行person.run方法;
  0008: return-void //返回void

  1. 全部全量方法调用dex指令查看;
public class Person {
   Person person;
   public void run() {
         person = new Person();
       person.run();
   }
}

编译成Person.class文件后,使用dx --dex --verbose --dump-to=a.txt --dump-method=Person.run --verbose-dump Person.class dx指令编译Person.run方法,删除无用信息后,得到文件内容以及解释如下:

Person.run:()V:
regs: 0002; ins: 0001; outs: 0001
  0000: new-instance v0, Person   //  1.在高速缓存中声明一个v0;2.将Person.class加载到方法区;3.在堆区实例化一个对象person;4.v0指向堆区的person对象;
  0002: invoke-direct {v0}, Person.<init>:()V    // 调用构造方法初始化person对象,并将返回值赋给v0
  0005: iput-object v0, v1, Person.person:LPerson;    //将v0赋值v1,则全局变量person(v1)就指向了堆区中的实例对象;
  0007: iget-object v0, v1, Person.person:LPerson;   //由于cpu不能直接使用堆区数据(v1),cpu将v1的值又读了一遍到v0中;
  0009: invoke-virtual {v0}, Person.run:()V // 调用v0执行person.run方法;
  000c: return-void

Q:为什么DCL单例需要使用 volatile关键字修饰?

A:当指令进行了重排,可能会出现Person.<init>:()V 指令在
0005: iput-object v0, v1, Person.person:LPerson 0007: iget-object v0, v1, Person.person:LPerson; 指令之后的情况,就会导致没有调用构造方法就使用了person对象的情况,而从引起问题;

结语

如果以上文章对您有一点点帮助,希望您不要吝啬的点个赞加个关注,您每一次小小的举动都是我坚持写作的不懈动力!ღ( ´・ᴗ・` )

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值