JVM内存区域介绍

来源:互联网 发布:minecraft java版 编辑:程序博客网 时间:2024/04/30 22:07

写博客的好处是,学过的知识及时记录下来,过段时间可以用来复习。另外,还能够帮助别人,因为我们自己遇到不懂的问题往往也是受益于别人的付出。
今天记录一下自己对于JVM内存区域的理解。
JVM内存主要可以分为五个区域:程序计数器、虚拟机栈、本地方法栈、堆、方法区。其中除了堆和方法区是线程共有的,其他几个区域都是线程私有的,下面分别介绍:
1、程序计数器
程序计数器是一块较小的内存,通过这个计数器来选取下一条需要执行的字节码指令。Java虚拟机的多线程是通过线程之间切换来轮流获得处理器的执行时间的,每个线程都有自己独立的程序计数器,它们互不影响,也就是线程私有的。如果执行的是Java方法,这里存放的是指令地址,如果执行的是Native方法,这里的值为空(Undefined)。并且这个区域不会出现OutOfMemoryError
2、虚拟机栈
虚拟机栈也是线程私有的,虚拟机栈描述的是Java方法执行的内存模型,执行每个方法的时候都会创建一个栈帧,用来存储局部变量表、操作数栈、方法出口等信息。局部变量表中存放了各种基本数据类型,对象引用类型,局部变量表在编译期间完成分配。
这个区域有两种异常情况:如果线程请求的栈深度大于虚拟机容许的最大深度,将抛出StackOverflowError异常;如果虚拟机栈可以动态扩展,但是扩展时无法申请到足够的内存,抛出OutOfMemoryError异常。
3、本地方法栈
本地方法栈与虚拟机栈的作用类似,只不过是虚拟机栈是为执行Java方法服务,而本地方法栈是为执行Native方法服务。
4、堆
Java对是由所有线程共享的一块内存区域,在虚拟机启动时创建,并且也是Java虚拟机管理管理的内存中最大的一块。Java堆主要用于存放对象实例以及数组,Java堆是垃圾回收的主要区域,也被成为“GC”堆。关于垃圾回收在下一篇博客中我会详细介绍。
5、方法区
方法区也是各个线程共享的内存区域,用于存储已经被虚拟机加载的类信息、常量、静态变量等数据。这个区域也会存在垃圾回收,不过回收的目标主要是针对常量池和对类型的卸载,不过由于类型的卸载条件比较苛刻,所以回收成绩难以令人满意。
最后再介绍一下对象的访问方式,上面已经介绍,在执行每个Java方法的时候都会创建一个栈帧,其中的局部变量表用来存储基本类型和对象引用(reference),而对象实例存储在堆中,那么如何通过引用访问对应的实例呢?介绍两种常用的方式:使用句柄访问和使用直接指针访问
使用句柄方式:是在Java堆中划出一块内存作为句柄池,refenence存储的是句柄的地址,而句柄中存储了实际的对象实例地址和类型信息地址,如下:这里写图片描述
使用直接指针:reference中存储的就是对象的地址,可以直接访问到实例,类型信息地址存储在对象内存中,如下:
这里写图片描述
使用句柄方式的最大好处是灵活,对象被移动时(在垃圾回收中是非常普遍的)只需要改变句柄中的指针即可,不需要修改reference;而使用直接指针的好处显而易见,就是节省了一次指针寻址的时间开销,因此速度更快。

0 0
原创粉丝点击