jvm 运行时数据区

图片描述

这里主要以HotSpot虚拟机做为描述对象java

1、程序计数器(Program Counter Register)

  1. 程序计数器是一块较小的内存空间,是当期线程执行字节码的行号指示器。
    字节码经过改变这个计数器的值来肯定下一个须要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等基础功能都须要依赖计数器来完成。算法

  2. java虚拟机的多线程是经过线程的轮流切换并分配处理器执行时间的方式来实现的,在任何一个肯定的时刻一个处理器都只会执行一条线程的指令。为了线程切换后恢复到正确的执行位置,每条线程都须要有一个独立的程序计数器。因此这块内存是“线程私有”的内存。数组

  3. 该区域是虚拟机规范中为一个没有规定任何OutOfMemoryError状况的区域。多线程

2、java虚拟机栈(Java Virtual Machine Stacks)

  1. Java虚拟机栈是线程私有的。spa

  2. 生命周期与线程相同。线程

  3. 描述的是java方法执行的内存模型:每个方法执行的同时都会建立一个栈帧(Starck Frame)用于存储局部变量表、操做数栈、动态连接等信息。每一个方法的开始调用到执行完成的过程都对应着一个栈帧在虚拟机栈中入栈到出栈的过程指针

  4. 局部变量表中存放了编译期可知的各类基本数据类型(boolean、byte、char、short、int、float、long、double)以及对象引用(reference类型,它不是对象自己,多是一个指向:对象起始地址的引用指针、对象句柄)和returnAddress类型(指向一条字节码指令的地址)。对象

  5. 虚拟机规范中对这块区域规定了两种异常情况:
    1> 若是线程请求的栈深度大于虚拟机所容许的深度将抛出StackOverflowError异常
    2> 若是虚拟机栈能够动态扩展,而扩展时没法申请到足够的内存,就会抛出OutOfMemoryError异常blog

3、本地方法栈(native Method Stack)

  1. 与虚拟机栈的做用很是相识,区别就是:虚拟机栈为虚拟机执行java方法服务,而本地方法栈为虚拟机使用到的native方法服务。SunHotSpot虚拟机把虚拟机栈和本地方法栈合并了。生命周期

  2. 与虚拟机栈同样本地方法栈也会抛出StackOverflowError和OutOfMemoryError异常

  3. 因此本地方法栈也是线程私有的

4、Java 堆(Java Heap)

从内存回收的角度来看因为如今的垃圾收集器都是采用分代收集的算法,因此这块区域又可细分为新生代和老年代,默认状况新生代又可分为一个Eden空间和两个Survivor空间。从内存分配的角度来看,线程共享的java heap可能须要划分出多个线程私有的分配缓冲区(Thread Local Allocation Buffer, TLAB)

  1. java堆是虚拟机所管理的内存中最大的一块区域,也是垃圾收集器管理的主要区域。

  2. 虚拟机启动时建立,全部线程共享。

  3. 惟一目的就是用来存放对象实例。全部的对象实例以及数组都要在堆上分配内存

  4. 能够经过-Xmx和-Xms来控制heap的可扩展性。

  5. 若是heap中没有足够的内存完成实例的分配,而且也没法再扩展时将会抛出OutOfMemoryError异常

5、方法区(Method Area)

对于HotSpot虚拟机上开发者也把这块区域成为“永久代”(Permanent Generation)。二者本质上并不等价,只是为了垃圾收集器能够像管理 Java 堆同样去管理这部分区域而把GC分代收集扩展到了这里。

  1. 线程共享的区域。

  2. 用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译(Just In Time,JIT编译器)后的代码等数据。

  3. 能够经过-XX:PermSize 和 -XX:MaxPermSize来设置这块区域的可扩展性

  4. 可能会抛出OutOfMemoryErrory

6、运行时常量池(Runtime Constant Pool)

这块区域是方法区的一部分。用于存放编译期生成的各类字面量和符号引用,这部份内容再类加载后存入方法区的运行时常量池中。既然是方法区的一部分,天然受到方法区内存的限制,当常量池没法申请到内存时会抛出OutOfMemoryErrory

相关文章
相关标签/搜索