class文件经过类加载过程被读入内存(运行时数据区),然后再交给执行引擎被翻译成机器码。
我们主要讲一个运行时数据区,从两个维度来讲:线程私有和线程共享。
线程私有:程序计数器、本地方法栈、虚拟机栈。
线程共享:堆、方法区。
线程私有:
程序计数器:
定义:当前线程正在执行的字节码指令的行号指示器。
为什么需要程序计数器:Java是多线程的,意味着会有线程切换,程序计数器可以保证多线程情况下程序能够正常执行。
详细内容:一个java文件被编译成class文件,然后被反编译后,可以看到每行代码前面都有一个数字。这一系列不连续的数字就是程序计数器所记录的东西,
可以简单理解为行号,之所以不连续,是因为每行代码的偏移量不同。
虚拟机栈:
定义:存储当前线程运行方法所需的数据、指令和返回地址等。
说明:Java虚拟机栈是基于线程的,哪怕只有一个main方法,也是以线程的方式运行的。在线程的生命周期中,参与计算的数据
会频繁的入栈和出栈,栈的生命周期和线程是一样的。
栈帧:栈里的每条数据,就是栈帧。在每个java方法被调用的时候,都会创建一个栈帧,并入栈。一旦完成相应的调用,则出栈。所有的栈帧都出栈后,线程也就结束了。
包含:每个栈帧都包含四个区域:局部变量表、操作数栈、动态连接、返回地址。
大小:栈的大小默认为1M,可以用参数 -Xss 调整大小,例如 -Xss256K
虚拟机栈:
局部变量表:用于存放局部变量。主要存储8大基础数据类型。如果是局部的一些对象,例如Object对象,我们只需要存放它的一个引用地址即可。
操作数栈:用于存放我们方法执行的操作数(操作步骤?)。举例:一个方法public void work(){int x=1;int y=2;int z=(x+y)*10; return z;},我们调用 work();
0: iconst_1 将int型1入操作数栈
1: istore_1 将操作数栈中栈顶int型数值出栈,存入局部变量表(下标为1的位置)
2: iconst_2 将int型2入操作数栈
3: istore_2 将操作数栈中栈顶int型数值出栈,存入局部变量表(下标为2的位置)
4: iload_1 将局部变量表中下标为1的int型数据入栈
5: iload_2 将局部变量表中下标为2的int型数据入栈
6: iadd 1)将栈顶两int型数值出栈 2)相加 3)将结果压入操作数栈
7: bipush 10 10的值扩展成int值入操作数栈
9: imul 1)将栈顶两int型数值出栈 2)相乘 3)将结果压入操作数栈
10: istore_3 将操作数栈顶int型数值出栈,存入局部变量表(下标为3的位置)
11: iload_3 将局部变量表中下标为3的int型数据入栈
12: ireturn 将操作数栈栈顶int型数值出栈,从当前方法返回int。
相关内容见17-01-43:24至53:36。
动态连接(17-01-57:00):跟Java语言多态性有关(需要运行时才能确定具体的方法)。
返回地址(也叫完成出口17-01-01:00:00):一个方法完成后,接下来需要执行什么就由这个完成出口决定。正常返回的话,会调用程序计数器中的地址作为返回;异常的话,通过异常处理器表(非栈帧中的)来确定。
本地方法栈(17-02-开始):跟虚拟机栈类似,虚拟机栈用于管理java函数的调用,而本地方法栈用于管理本地方法(native方法,由C语言实现)的调用。
当一个JVM创建的线程调用native方法后,JVM不再为其在虚拟机栈中创建栈帧,JVM只是简单地动态链接并直接调用native方法。
虚拟机规范并无强制规定,各版本虚拟机自由实现本地方法栈。HotSpot直接把本地方法栈和虚拟机栈合二为一。
线程共享(17-02-06:00):
小问题:线程共享为什么要分为方法区和堆,为什么不直接用一块区域?
堆:对象、数组。需要被频繁回收的。
方法区:类信息、常量、静态变量、即时编译期编译后的代码。这些信息被回收的难度是很大的。分为堆和方法区体现了动静结合的思想。即偏静态的数据放在方法区,需要频繁地动态创建和回收的数据放在堆中。
方法区:主要是用来存放已被虚拟机加载的类相关信息,包括类信息、静态变量、常量、运行时常量池、字符串常量池。
堆:对象实例(几乎所有)、数组。分为新生代和老年代。新生代又分为:Eden空间、From Survivor空间、To Survivor空间,空间大小比例为8:1:1。
1.2、我在new一个对象的时候,它是被放在内存的那一块区域
-------------------------- 《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》无偿开源 徽信搜索公众号【编程进阶路】 ----
成员变量和局部变量。
Java中几乎所有的对象实例、数组都会被放在堆中。
堆又分为老年代和新生代。新生代又分为:Eden空间、From Survivor空间、To Survivor空间,空间大小比例为8:1:1。
所以成员变量也会被放在堆中。