运行时数据区域

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

Comments

Your browser is out-of-date!

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

×