美文网首页UITJava技术干货
Java之JVM的运行时数据区

Java之JVM的运行时数据区

作者: Jason_Sam | 来源:发表于2019-05-20 17:05 被阅读1次

JVM运行时数据区域

运行时数据区域

一、程序计数器

程序计数器占据JVM内存的一块小内存空间,且为每条线程私有,可以视为当前线程的字节码行号指示器。字节码解释器可以通过改变这个程序计数器来选取下一条执行的命令。具有以下两个作用:

1. 实现顺序控制,按照程序计数器的指令顺序执行,如分支、循环、异常等。

2. 实现线程恢复。程序计数器记录线程切换前的位置,当线程恢复时,可从记录位置恢复。

二、虚拟机栈

虚拟机栈时由一组栈帧组成的,每个栈帧包含Java局部变量表(byte、boolean、char、short、int、long、float、double)、操作数栈、动态链接方法、方法出入口信息。

虚拟机栈会出现两种异常:StackOverFlowError和OutOfMemoryError。

StackOverFlowError:若JVM栈内存大小不允许动态扩展,那么当前线程请求栈的深度超过JVM栈的最大深度的时候。

OutOfMemoryError:若JVM栈内存大小不允许动态扩展,且当前线程请求栈内存用完。

三、本地方法栈

类似于虚拟机栈,区别在于虚拟机栈执行的是Java方法服务,本地方法栈执行的是Native方法服务。本地方法栈也会出现StackOverFlowError和OutOfMemoryError异常。

四、堆

堆是JVM内存管理最重要的区域,而且堆内存是线程共享的,那么是线程不安全的,且在JVM启动之时创建。所有通过new创建的对象的内存都分配在堆中,JVM的GC发生最频繁的区域就是堆中。操作系统有一个记录空闲内存地址的链表,当系统收到程序的申请时,会遍历该链表,寻找第一个空间大于所申请空间的堆结点,然后将该结点从空闲结点链表中删除,并将该结点的空间分配给程序,另外,对于大多数系统,会在这块内存空间中的首地址处记录本次分配的大小,这样代码中的delete语句才能正确的释放本内存空间。但由于找到的堆结点的大小不一定正好等于申请的大小,系统会自动的将多余的那部分重新放入空闲链表中。堆内存是向高地址扩展的数据结构,是不连续的内存区域。由于系统是用链表来存储的空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存。由此可见,堆获得的空间比较灵活,也比较大

五、方法区

它保存方法代码和符号表。存放了要加载的类信息、静态变量、final类型的常量、属性和方法信息。方法区是线程共享的,但内存数据相对稳定,只在特定的条件下才会发生GC。在内存超过允许范围,也会发生OOM。方法区也是堆中的一部分,就是我们通常所说的Java堆中的永久区 Permanet Generation,大小可以通过参数来设置,可以通过-XX:PermSize指定初始值,-XX:MaxPermSize指定最大值。

相关文章

网友评论

    本文标题:Java之JVM的运行时数据区

    本文链接:https://www.haomeiwen.com/subject/fuvkzqtx.html