title: Jvm的内存区域划分
date: 2020-7-10 22:39:33
categories:
- JVM
tags: - JVM
- java
Jvm的内存区域划分
一般将JVM运行时的数据区域划分为五个区域:程序计数器、java虚拟机栈和本地方法栈、java堆、方法区和直接内存。
学习每个区域的内容时,主要解决三个问题它存在作用、主要内容或基本原理、需要注意的特别之处,带着这三个问题,我们就能很好的了解它了。
1.程序计数器
程序计数器作用:程序执行的指示器,负责指向下一条要执行字节码指令,我们程序中的循环、跳转、异常的处理都需要它来实现。
基本原理:字节码解释器通过修改程序计数器的值指向下一条要执行的指令,在执行Java方法时,程序计数器指向方法的入口,而执行本地方法时值为null。
特点:程序计数器属于线程私有属性,每一个线程都有一个对应的程序计数器,此外它是《JVM规范》中唯一没有规定OutOfMemoryError的区域。
2.Java虚拟机栈和本地方法栈
作用:java虚拟机栈是Java方法执行的线程内存模型
基本原理:在进入一个方法时,Jvm会在虚拟机栈中创建一个栈帧,用于存储方法中的局部变量表、出口信息等。方法从开始执行到结束的过程就对应栈帧入栈到出栈的过程。
内容:既然时方法的内存模型,那么方法中的基本变量类型、对象引用指针、返回值等一些信息都存储于局部变量表中。值得一提的是,在进入一个方法时,方法栈帧所需要的大小是已知的。JVM通过槽来确定方法的内存大小,如一个Long对应一个槽,int对应一个槽,对象引用对应一个槽。
特点:Java虚拟机栈属于线程私有区域,当栈帧的深度超过最大允许的深度时抛出StackOverFlowError异常,当无法申请到足够的空间时抛出OutOfMemoryError异常。
本地方法栈于java虚拟机栈极其相似,区别是本地方法栈负责执行本地方法,这里就不再赘述了。
3.Java堆
作用:在《java虚拟机规范》中对它的描述是:所有的对象以及数组都当在堆上分配。
基本原理:当碰到new时,JVM在确认对象的类已经正确加载后,在java堆中为其划分一块空间,首先初始化为0。之后再执行init()为其赋值上我们期望的值。值得一提的是,java堆是垃圾回收机制(GC)的主要回收区域,也是JVM中最大的一块区域。
特点:java堆属于线程共享区域,但有时为了提升对象分配的效率,java堆可以划分多个线程私有的缓存区。当无法申请到足够的空间是抛出OutOfMemoryError。
4.方法区
作用:用于存储已被虚拟机加载的类型信息、常量、编译后的代码缓存、静态变量等
特点:属于线程共享区域,无法申请到足够的空间时抛出OutOfMemoryError。
方法区内包括运行时的常量池,里面主要存储了类的版本、接口、方法、字段等描述信息还有各种字面量和符号引用。
5.直接内存
作用:直接内存并不属于java虚拟机内存,而是在虚拟机之外划分的一块区域,我们可以通过DirectByteBuffer对象对其进行操作,目的为了避免在java堆和OS堆中来回复制数据。
特点:申请不大足够的空间时,抛出OutOfMemoryError,此外,这部分内存的回收由操作系统来执行。