运行时数据区域

java虚拟机运行时数据区域

1 程序计数器

• 较小的内存区域,存储当前线程执行的字节码的行号。
• 线程私有。
• 如果执行java方法,存储的是行号;如果执行的是nativ方法,值为空。
• 字节码解释器通过改变计数器的值来选取下一条执行的字节码指令。
• 唯一一个在Java虚拟机规范中没有规定任何OutOfMemoryError情况的区域。

2 java虚拟机栈

• 线程私有。
• 生命周期同线程一样。
• 由一个个栈帧组成。一个栈帧存储局部变量表、操作数栈、动态链接、方法出口。一个方法的调用对应一个栈帧的创建、方法的调用与返回就是栈帧入栈出栈的过程。
• 局部变量表存储编译期可知的各种基本数据类型、对象引用(对应指向对象的地址或者指向对象的句柄)、returnAddress类型。
• 操作数栈从局部变量表中取得变量入栈、然后出栈进行运算、将运算结果存回栈,出栈存入局部变量表。

存在两种异常:
如果线程请求的栈深度大于虚拟机所允许的深度, 将抛出StackOverflowError异常;
如果虚拟机栈可以动态扩展( 当前大部分的Java虚拟机都可动态扩展, 只不过Java虚拟机规范中也允许固定长度的虚拟机栈) , 如果扩展时无法申请到足够的内存, 就会抛出OutOfMemoryError异常。

3本地方法栈

• java虚拟机栈为java方法调用服务,本地方法栈为native方法调用服务。
• 本地方法栈区域也会抛出StackOverflowError和OutOfMemoryError异常。 

4java堆

• 线程共享。
• 虚拟机启动时创建。java虚拟机管理的最大的内存区域。
• 存放对象实例,几乎所有的对象实例都在堆上分配。
• java堆可以处于物理上不连续的内存空间中,只要逻辑上是连续的即可。
• 如果在堆中没有内存完成实例分配, 并且堆也无法再扩展时, 将会抛出OutOfMemoryError异常。 
• 可分为新生代和老年代,新生代又可分为Eden空间、 From Survivor空间、 To Survivor空间 ,划分的目的是为了更好的内存回收和分配。

5方法区

• 线程共享。
• 存储虚拟机加载的类信息、常量、静态变量、编译后的代码。
• 不需要连续的内存,可以选择固定大小和可扩展,同时可以设置不进行垃圾收集。
• 内存回收主要针对常量池和对类型的卸载。

6运行时常量池

• 存储编译期的字面量和符号引用。
• 具有动态性,并非预置入Class文件中常量池的内容才能进入方法区运行时常量池, 运行期间也可能将新的常量放入池中,如String类的intern( ) 方法。 

从更高的一个维度再次来看JVM和系统调用之间的关系:

如何通过参数来控制各区域的内存大小

控制参数
-Xms设置堆的最小空间大小。
-Xmx设置堆的最大空间大小。
-XX:NewSize设置新生代最小空间大小。
-XX:MaxNewSize设置新生代最大空间大小。
-XX:PermSize设置永久代最小空间大小。
-XX:MaxPermSize设置永久代最大空间大小。
-Xss设置每个线程的堆栈大小。

ref:https://www.cnblogs.com/ityouknow/p/5610232.html

第三章-机器表示

1数据类型字节大小


每个寄存器都有特殊的用途,它们的名字反应了这些不同的用途。
指令可以对这16个寄存器的低位字节中存放的不同大小的数据进行操作。
字节级操作可以访问最低的字节,16位操作可以访问最低的2个字节,32位操作可以访问最低的2个字节,64位操作可以访问整个寄存器。

2 寄存器


当指令以寄存器为目标时,对于生成小于8字节结果的指令,寄存器中剩余的字节会怎么样,对此有两条规则:生成1字节和两字节数字的指令会保持剩下的字节不变,生成4字节数字的指令会把高位4个字节置为0。
%rsp:栈指针,用来指明运行时栈的结束位置。
大多数指令有一个或多个操作数,指示出执行一个操作中要使用的原数据值,以及放置结果的目的位置。

3 操作数格式

4 数据传送指令mov

5 栈操作

6 整数算术操作

7条件码

8比较和测试指令

9 set指令

10 jump指令

第三章-过程:过程提供一种封装

第一章-计算机系统

1.计算机执行

计算机使用8位二进制位组成的字节表示的唯一的整数来表示字符。
系统中所有的信息,都是由一串比特序列组成的。区分不同数据对象的唯一方法是读取数据对象的上下文 。
C语句-低级机器语言指令-可执行目标程序(以二进制磁盘文件存储,也称可执行目标文件)。
从程序文件翻译成目标文件。翻译过程分为四个阶段,预处理器,编译期,汇编器,链接器,构成了编译系统。

hello.o目标文件中调用了库函数printf,而库函数存于与已经编译好的另一个目标文件printf.o中,链接器用于将其合并。

2.系统的硬件组成

总线被设计成传送定长的字节块,称之为字。字中的字节数(即字长)是一个基本的系统参数,各个系统中不尽相同。字长是4个字节(32位),8个字节(64位)。
控制器与适配器:控制器集成在IO设备上或者主板芯片上,适配器作为外设,插在主板插槽上。

寄存器,程序计数器,大小为一个字。处理器核心。
寄存器文件:小的存储设备,由一些单个字长的寄存器组成。
加载:从主存复制一个字节或者一个字到寄存器,以覆盖寄存器原来的内容。内存->寄存器
存储:从寄存器复制一个字节或者一个字到内存的某个位置,以覆盖这个位置上原来的内容。寄存器->内存
操作:把连个寄存器的内容赋值到ALU,ALU对这连个字做算术运算,并将结果存放到一个寄存器中,以覆盖该寄存器中原来的内容。
跳转:从指令本身抽取一个字,并将这个字复制到程序计数器汇(P;C)中,以覆盖PC中原来的值。

利用直接存储器存取(DMA),数据不通过寄存器从磁盘直接到内存。

3.操作系统

进程是操作系统对一个正在运行的程序的一种抽象。
并发执行:一个进程的指令和另一个进程的指令是交错执行的。
处理器在进程间切换,实现一个CPU并发执行多个进程。
操作系统实现交错执行的机制称为上下文切换。

操作系统保持跟踪进程运行所需的所有状态信息。这种状态,就是上下文。(包括PC和寄存器文件的当前值及主存的内容)。
从一个进程到另一个进程的转换是由操作系统内行人管理的。内核是操作系统代码常驻主存的部分。
应用程序运行(用户态)-执行某些操作(文件读写)-进行系统调用-控制权转到操作系统(内核态)-内核执行请求操作-返回应用程序(用户态)

内核不是一个进程,是系统管理所有进程代码和数据结构的集合。

4.并发与并行

并发:指一个同时具有多个活动的系统。
并行:用并发来使一个系统运行的更快。
线程级并发


超线程:同时多线程,一个CPU执行多个控制流的技术。

指令级并行:处理器同时执行多条指令。
单指令、多数据并行

第二章 信息表示

1虚拟地址

字长:指明指针数据的标称大小。
虚拟地址是以一个字来编码的。
字长决定的最重要的系统参数是虚拟地址空间的最大大小。
32位字长限制虚拟地址空间为4GB 4*10^9 字节。64位字长限制虚拟机地址空间为16EB。

2逻辑运算与位运算

位运算:& | ^ 位运算 0 1
逻辑运算:&& || ! 逻辑运算非0为1,true 0为0 ,false 逻辑运算如果对第一个参数求值就能确定表达式的结果,那么逻辑运算符就不会对第二个参数求值。
移位运算:移位运算从左至右是可结合的 x>>j>>k等价于x>>k>>j
左移:右端补0
右移:逻辑右移 算术右移
逻辑右移:在左端补0
算术右移:左端补k个最高有效位的值 对于有符号数运算有用
C语言标准:几乎所有的编译器/机器组合对有符号数使用算术右移 ,对于无符号数,右移采用逻辑右移。
java标准:x>>k为算术右移,x>>>k为逻辑右移。
移位量k小于数值位数w,如果k>=w,k=k mod w。

3整数表示:

4编码

1无符号数编码

2.补码编码

补码编码,最高位解释为负权,也称之为符号位,权重为-2^(w-1),无符号表示的权重的负数。符号位为1,表示值为负,值为0,表示非负。

补码的范围是不对称的:|Tmin|=|Tmax|+1
原因:一半的位模式(符号位为1的数)表示负数,另一半的位(符号位设置为0的数)表示非负数。因为0是非负数,这意味能表示的正数比负数少一个。
最大的无符号数刚好比补码的最大值的两倍大1:Umax=2Tmax+1
-1和Umax具有同样的位表示,一个全1的串。
c标准没有要求使用补码表示有符号整数,但是几乎所有的机器都是这么做的。
使用补码来编码有符号数,具有图2-9和2-10的典型的取值范围。
java只有有符号数。在java标准中,整数数据类型的取值采用补码表示。在java中单字节数据类型称为byte,而不是char。

3编码转换

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×