Java虚拟机在执行java程序的过程中会它所管理的内存划分为若干各不同的数据区,包括:
1.程序计数器
占用较小的内存空间,可以看作是当前线程所执行的字节码的行号指示器,通过改变这个计数器的值来选取下一条需要执行的字节码指令。由于java多线程是通过轮流切换并分配处理器执行时间的方式来实现的,在一个确定的时刻,一个处理器(对于多核处理器来说是一个内核)只能执行一条线程中的指令,为了线程切换后能恢复到正确的执行位置,每个线程都有一个计数器,各线程间的计数器互不影响。
2.栈空间(虚拟机栈)
与计数器一样,栈也是线程私有的,其生命周期与当前线程相同,为java方法服务。每个方法在执行的同时会创建一个栈帧用于存储局部变量表、操作数栈、动态连接、方法出口等信息,每个方法从调用到执行完成的过程,对应着一个栈帧在栈空间中入栈到出栈的过程。栈的特性是后进先出(last in first out—lifo)。
可能会抛出StackOverflowError异常、OutOfMemoryError异常。
3.本地方法栈
为虚拟机使用到的native方法服务。在虚拟机中对本地方法栈中方法使用的语言、使用方式与数据结构并没有强制规定,因此具体的虚拟机可以自由的实现它。甚至有些虚拟机直接把本地方法栈与虚拟机栈合二为一,如Sun HotSpot虚拟机。
可能会抛出StackOverflowError异常、OutOfMemoryError异常。
4.堆空间
java堆是所有线程共享的,也是JVM所管理的内存中最大的一块,在JVM启动时创建。此区域的唯一目的就是存放对象实例,同时也是垃圾收集管理的主要区域,很多时候被称为“GC堆”。根据JVM规范,堆可以处于物理上不连续的内存空间,只要逻辑上连续即可。
可能会抛出OutOfMemoryError异常。
5.方法区
是所有线程共享的,主要用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。JVM规范把方法区描述为堆的一个逻辑部分,但它有一个别名叫Non-Heap(非堆)。这个区域的垃圾回收主要是针对常量池的回收和对类型的卸载,比较少出现垃圾收集行为。
6.运行时常量池
Runtime Constant Pool是方法区的一部分
JDK1.4中新加入了NIO(New Input/Output)类,引入了一种基于Channel与Buffer的I/O方式,它可以使用native函数库直接分配内存,这部分内存不是JVM运行时数据的一部分。
网友评论