java内存结构学习的一种打开方式

用Java开发已经四年,中途学了python,Scala,接触这些开发语言后,总感觉Java就像老奶奶裹脚——又臭又长。然,Java虐我千百遍,我待Java如初恋。聊起Java,不得不谈Java的内存结构,请注意,要区别Java内存模型(JMM,关于happens-before、读写屏障啥的)

结构图

java内存结构包括5大部分,先来一张图围观一下:
java内存结构学习的一种打开方式
其中堆存放的有对象实例、数组;局部变量表存储各种基本数据类型,对象引用(区别对象实例,这个是对象在堆中的地址);方法区存储已被虚拟机加载的类信息、常量、静态变量、即使编译器编译后的代码等数据。

what?这些和我学习Java有毛线关系?来,请思考下面这道题中i、j、k的值:

    public static void main(String[] args) {
        int i =1;
        i =i++;
        int j =i++;
        int k = i + ++i *i++;
        System.out.println("i = "+i);
        System.out.println("j = "+j);
        System.out.println("k = "+k);
    }

我们需要知道,程序的执行就是不断入栈出栈的过程,int i =1,就是在本地变量表中存入i的值1,先来撸张初始状态的图。
java内存结构学习的一种打开方式

i =i++;

这个操作执行了下面的过程:

  • 将i 的值1压入操作数栈;
  • 修改局部变量表中的i值,为2;
  • 赋值语句执行出栈操作,将操作数栈中i的值1返回给局部变量表中的i。

这个操作执行后你会神奇的发现:原来啥子也没有变。

int j =i++;

这个操作执行了下面的过程:

  • 在局部变量表中添加变量j;
  • 将i的值入栈,为1;
  • 修改局部变量表中的i值,为2;
  • 赋值语句将操作数栈中的i出栈,赋值给j,为1;

此时内存中的变量状态如下:
java内存结构学习的一种打开方式

int k = i + ++i *i++;

这个操作执行了下面的过程:

  • 在局部变量表中添加变量k;
  • 将i的值加入操作数栈,为2;
  • 将局部变量表中的i值加1,为3(注意++i和i++执行顺序的区别);
  • 将局部变量表中的i值加入操作数栈,为3(第二个i);
  • 将局部变量表中的i值再次加入操作数栈,为3(第三个i);
  • 将局部变量表中的i值加1,为4;
  • 赋值语句执行出栈操作 3+3+2,将值11赋值给k;

下面的图是没有执行赋值语句前的内存中变量状态:
java内存结构学习的一种打开方式
相信你已经知道最后的结果了吧:

i = 4
j = 1
k = 11

你是不是要感叹下:原来还能这样…