Java虚拟机学习笔记-运行时数据区(内存区)

Java虚拟机在执行java程序过程中把内存划分成不同的数据区域:比如常见的堆栈、方法区、静态域、常量池等。以下是java运行时的数据区域图解:
这里写图片描述

1、程序计数器
在运行时数据区中程序计数器是一块分配较小内存的空间,它的主要功能可以描述为jvm字节码编译的位置记录器,字节码解释器工作时就是通过改变此程序计数器的值来选取下一条需要执行的字节码指令。
java虚拟机的多线程是通过线程之间的轮流切换并分配处理器执行时间的方式来实现。在任何确定的时刻,一个处理器只会执行一条线程中的指令。因此这样为了能在不同线程之间的切换并回到正确位置,可以知道每个线程都必须有一个独立 的程序计数器。。并且各个线程之间的程序计数器互相独立。在参考书中也把这类内存区域叫做“”线程私有“”的内存。
程序计数器的逻辑为:
1.如果线程正在执行的是一个java方法,那么计数器记录的是正在执行的虚拟机字节码指令地址
2.如果执行的native方法,计数器当中的内容应当是空(undefined) native方法就是原生态方法,由于java语言本身不能对操作系统底层进行访问和操作,但是可以通过JNI接口调用其他语言来实现对底层的访问。这个方法就是native方法。
3.此内存区域在java的虚拟机规范当中是唯一一个没有规定OutOfMemoryError的区域

2、java虚拟机栈
在这里是说明一下,java栈总是和线程关联在一起,每当创建一个线程时,JVM就会为这个线程创建一个对应的java栈。在这个java栈中又会包含多个栈帧,每运行一个方法就创建一个栈帧,用于存储局部变量表(用来存储编译器可知的各种基本数据类型和对象引用和returnAddress)、操作栈、方法返回值等。每一个方法从调用直至执行完成的过程,就对应一个栈帧在java栈中入栈到出栈的过程。所以java栈是现成私有的。所以在java栈中的对象和数据总是跟随线程生,伴随线程灭的(自动回收垃圾)。也就是说后面的垃圾回收机制在Java栈中就不存在。在栈中主要出现的异常为:1.当线程请求的栈深度超过虚拟机所允许的栈深度,抛出StackOverflowError异常;2.当栈扩展(栈是可以动态扩展的)无法申请到足够的内存时抛出OOM(OutOfMemoryErroor)异常。

3.Java堆:在java内存管理中堆(heap)是java虚拟机内存分配空间中最大的一块,它的目的就是存储新建的对象实例,所有的对象实例或者数组都(考虑绝对,忽略JIT编译器的情况)在这里分配内存空间。所以java堆对于所有线程是共有的。当然后面要说的方法区也是线程共享的。这就决定了垃圾回收器的主要工作范围就是堆和方法区。这里主要出现的异常为:如果堆内存无法满足实例的分配,并且堆无法再进行扩展时将抛出OOM(OutOfMemoryErroor)异常。

4.方法区(Method Area):前面说到过,它和堆都是线程共享的。方法区从字面意思上可以知道它的功能,用来存储类信息。包括常量池、静态变量、构造函数等。虽然JVM规范把方法区描述为堆的一个逻辑部分, 但它却有个别名non-heap(非堆)。方法区还包含一个运行时常量池。其存在的主要异常为:当方法区无法满足内存分配需求时,将抛出OOM(OutOfMemoryErroor)异常。

5.本地方法栈(Native Method Stack):和java栈的作用差不多,只不过是为JVM使用到的native方法服务的。也是会出现StackOverflowError和OutOfMemoryError异常。

6.运行时常量池(Constant Pool Table):这是在方法区中的一个重要概念。常量池是java的class结构中的一部分。用于存放编译生成的各种字面量和字符常量、符号引用等。在类加载之后会把这些加载到运行时常量池中。class文件的结构有:魔数(用来识别class文件的特殊表示)、版本号、字段、方法、接口的信息描述,还有常量池(字面量和符号引用)。

在了解了内存划分之后,记录一下内存的分配机制:编译时就能够确定的内存就是静态内存,即内存是固定的,系统一次性分配,比如int类型变量;
动态内存分配就是在程序执行时才知道要分配的存储空间大小,比如java对象的内存空间。根据上面我们知道,java栈、程序计数器、本地方法栈都是线程私有的,线程生就生,线程灭就灭,栈中的栈帧随着方法的结束也会撤销,内存自然就跟着回收了。所以这几个区域的内存分配与回收是确定的,我们不需要管的。但是java堆和方法区则不一样,我们只有在程序运行期间才知道会创建哪些对象,所以这部分内存的分配和回收都是动态的。一般我们所说的垃圾回收也是针对的这一部分。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章