(一)JVM-Java运行时数据区域
运行时数据区
java虚拟机在执行java程序的时候会将内存划分为如下几个区域,有的区域是线程共享的,但有的是区域则是线程隔离。
程序计数器(Promgram Counter Register)
- 程序计数器是一块较小的内存空间
- 字节码解释器工作时通过改变计数器的值来选取下一条字节码指令,程序分治,循环,跳转异常处理等都由它完成。
- 任何一个确定的时刻,一个处理器都只会执行一条线程中的命令,每个线程都有独立的程序计数器。在多线程的情况下,程序计数器用于记录当前线程执行的位置,从而当线程被切换回来的时候能够知道该线程上次运行到哪儿,所以它线程私有的。
- 唯一没有规定OutOfMEmoryError的区域
java虚拟机栈
- 线程私有
- 生命周期和线程相同,是java方法执行的内存模型
- 在执行方法时会先创建栈帧(stack frame)用于存放局部变量表,操作数栈,动态链接,方法出口等信息。每一个方法调用的过程就是对应栈帧出栈入栈的过程。
- 局部变量表:存放编译器可见的各种基本数据类型,对象引用类型,long和double会占用两个局部变量空间。
- 如果线程请求的栈深度超过限制则会抛出StackOVerflowError。如果虚拟机在申请内存时无法申请到足够的内存则会抛出OutOfMemoryError。
本地方法栈
- 提供native方法服务。
java堆
- java堆是java虚拟机管理内存中最大的一块。
- 线程共享,存放几乎所有的对象实例。
- 垃圾搜集器主要管理的区域。
- 可通过-Xmx -Xms来限制此区域的内存大小。
- 无法申请到内存时抛出OutOfMemoryError异常
方法区
- 线程共享,是堆逻辑分区的一部分
- 存放虚拟机加载的类型信息、常量、静态变量等
- 虚拟机规范将其划分为堆的一个逻辑分区
- 无法申请到内存时抛出OutOfMemoryError异常
运行时常量池
- 方法区的一部分,用于存放编译期生成的各种字面量和符号引用,这部分内容在类加载完成后进入方法区的常量池
- 具有动态性,运行期间也可将新的常量放入池中,比如String的intern方法。
- 无法申请到内存时抛出OutOfMemoryError异常。
直接内存
- 直接内存不是虚拟机运行时数据区域的一部分,是堆外内存,比如NIO就是使用直接内存,受限制于本机内存,当申请不到内存时也会抛出OutOfMemoryError。
- 优点是具有更快的速度,缺点是不受jvm内存限制。
关注下方微信公众号,一起阅读经典书籍