JVM(1)-Java运行时数据区域

Java虚拟机在执行Java程序时会把它所管理的内存划分为若干个数据区域, 有的区域随着虚拟机进程的启动而存在, 如: 方法区和Java堆  而有些区域依赖用户线程的启动和结束而创建和销毁, 如: 程序计数器、虚拟机栈和本地方法栈

下面就来介绍Java虚拟机所管理的内存所包含的几个数据区域:

1.程序计数器

程序计数器是一块较小的内存空间,可以看作当前线程所执行的字节码的行号指示器。

程序计数器的作用: Java虚拟机的多线程是通过线程轮流切换并分配处理器执行时间的方式来实现, 任何时刻,一个内核都只会执行一条线程中的指令。因此,为了线程切换后能够恢复到正确的执行位置,每条线程都需要一个独立的程序计数器。我们称这类内存区域为“线程私有”内存。此内存区域是唯一一个没有规定任何OutOfMemoryError情况的区域。

2.Java虚拟机栈

Java虚拟机栈同程序计数器一样也是线程所私有的,其生命周期与线程相同。

虚拟机栈描述的是Java方法执行的内存模型每一个方法在执行的同时都会创建一个栈帧用于存储局部变量表、操作数栈、动态链接、和方法输出等信息。每一个方法从调用直到执行完成的过程,都对应着一个栈帧在虚拟机栈中的入栈到出栈的过程。

Java虚拟机栈的两种异常状况:1.线程请求的栈深度大于虚拟机所允许的深度时,将抛出StackOverflowError异常      2.虚拟机栈可以动态扩展时,如果扩展时无法申请到足够的内存,就会抛出OutOfMemoryError异常。

3.本地方法栈

本地方法栈与虚拟机栈的作用非常相似。区别在于:Java虚拟机栈为虚拟机执行Java方法,而本地方法栈则为虚拟机的native方法服务。本地方法栈也有StackOverflowError异常 和 OutOfMemoryError异常

4.Java堆

Java堆通常是Java虚拟机所管理的内存中最大的一块。Java堆是所有线程共享的一块内存区域,在虚拟机启动时创建。Java堆的唯一目的就是存放对象实例,几乎所有的对象实例都在堆上分配内存。Java堆是垃圾收集管理的主要区域。   Java堆可以细分为: 新生代,老年代;   Java堆可以处于物理上不连续的内存空间中,只要逻辑上连续即可。堆的扩展通过jvm参数-Xmx(ps:最大堆内存) 和 -Xms(ps:最小堆内存)来控制,如果堆中没有内存来完成实例分配,也无法再进行扩展时,将会抛出OutOfMemoryError异常。

5.方法区

与Java堆一样,方法区也是线程所共享的内存区域,用于存储那些已被虚拟机加载的类信息、常量、静态变量、及时编译器编译后的代码等数据。方法区有时候也被叫做“永久代”,方法区的内存的回收主要是针对常量池的回收和对类型的卸载,但结果通常不令人满意。当方法区无法满足内存分配需求时,将抛出OutOfMemoryError异常。

6.运行时常量池

运行时常量是方法区的一部分。Class文件中的常量池用于存放编译期生成的各种字面量和符号引用,这部分内容在类加载后进入方法区的运行时常量池。   运行时常量池相对于Class文件常量池的另外一个重要特征是具备动态性,像运行期间也可能将新的常量放入池中,该特性被利用最多的就是String类的intern()方法。  内存方面收到方法区内存的限制,当常量池无法申请到内存时将会抛出OutOfMemoryError异常。

补充:直接内存

直接内存并不是虚拟机运行时数据区的一部分 ,但是这部分内存被频繁使用,也有可能导致OutOfMemoryError异常出现

本机的直接内存的分配不会收到Java堆的限制,但是肯定的一点是,直接内存收到本机内存大小以及处理器寻址空间的限制。

猜你喜欢

转载自blog.csdn.net/hudaJY/article/details/82947196