深度理解JVM-----运行时数据区域

如下内容部分转载于: CS-Notesjava

程序计数器(Program Counter Register)

记录正在执行的虚拟机字节码指令的地址(若是正在执行的是本地方法则为空)。git

ps:什么是本地方法?github

本地方法是由其余语言(如C、C++ 或其余汇编语言)编写,编译成和处理器相关的代码。本地方法保存在动态链接库中,格式是各个平台专用的,运行中的java程序调用本地方法时,虚拟机装载包含这个本地方法的动态库,并调用这个方法。

学过计算机组成的同窗将不难理解,经过计数器寻找到下一条指令数组

每个线程都必须存在一个程序计数器,由于一个处理器在同一时间只能处理一个线程(对于单核处理器,或者多核处理器的一个内核)函数

经过程序计数器,来记录每个线程所执行到的位置,方便线程直接的切换性能


Java虚拟机栈(Java Virtual Machine Stacks)

虚拟机栈也是每一个线程私有的,它的生命周期与线程相同,虚拟机栈描述的是Java方法执行的内存模型spa

包括:局部变量表,操做数栈,动态连接,方法出口等信息线程

每个方法的从执行到完成,就表明着一个栈的在虚拟机栈中的入栈和出栈的过程3d

该区域可能抛出如下异常对象

StackOverflowError :当线程请求的栈深度超过最大值,如递归形成的方法屡次调用

OutOfMemoryError :栈进行动态扩展时若是没法申请到足够内存


本地方法栈(Native Method Stack)

本地方法(Native Method): 由其余语言(如C、C++ 或其余汇编语言)编写,编译成和处理器相关的代码。本地方法保存在动态链接库中,格

式是各个平台专用的,运行中的java程序调用本地方法时,虚拟机装载包含这个本地方法的动态库,并调用这个方法。

具体用法和虚拟机栈相似,只不过它服务的对象为本地方法,在Sun公司的HotSpot虚拟机中,就将把本地方法栈和虚拟机栈合二为一

一样会出现 StackOverflowErrorOutOfMemoryError 错误


堆(Heap)

堆是一块被Java全部线程共享的一块内存区域,主要用于存放对象实例和数组

在堆中能够分为

  • 新生代(Young Generation)
  • 老年代(Old Generation)

咱们常说的 GC(Garbage Collected Heap) 说的就是整理这一块的内存区域

堆的内存区域不须要连续,能够动态的增长内存,增长失败会抛出 OutOfMemoryError 异常。

能够经过 -Xms 和 -Xmx 这两个虚拟机参数来指定一个程序的堆内存大小,第一个参数设置初始值,第二个参数设置最大值。

java -Xms1M -Xmx2M HackTheJava

方法区(Method Area)

方法区和堆同样,也谁被全部线程共享的内存区域,用于存储已被虚拟机加载的类,常量,静态变量,即时编译器编译后的代码等数据

有一个别名 Non-Heap(非堆),在HotSpot虚拟机上人们习惯称之为 永久代(Permanent Generation)

方法区为JVM的一个规范,定义为存放某些数据,在不一样的虚拟机中存在着不一样的实现

由于在HotSpot虚拟机上,也存在这方法区的垃圾回收,因此称为永久代。

在永久代中常常会产生对永久代的回收不彻底致使内存泄漏爆出OutOfMemoryError的错误

为了更容易管理方法区,在JDK8中,废弃了永久代,改用元空间代替

方法区移至到元空间中,元空间存储于本地内存中,而不是在JVM虚拟机

方法区是一个 JVM 规范,永久代与元空间都是其一种实现方式。

在 JDK 1.8 以后,原来永久代的数据被分到了堆和元空间中。元空间存储类的元信息,静态变量和常量池等放入堆中。


运行时的常量池(Runtime Constant Pool)

运行时的常量池是方法区的一部分,用于存放编译期产生的各类字面量和符号引用

这部份内容将在类加载后进去方法区的运行时常量池存放

除了在编译期生成的常量,还容许动态生成,例如 String 类的 intern()。


直接内存(Direct Memory)

直接内存并非虚拟机运行时数据区的一部分,也不是Java虚拟机规范中定义的内存区域

可是这个区域的内存被频繁使用,任然会形成OutOfMemoryError的异常

JDK 1.4 中新引入了 NIO 类,它可使用 Native 函数库直接分配堆外内存,而后经过 Java 堆里的 DirectByteBuffer 对象做为这块内存的引用进行操做。

这样能在一些场景中显著提升性能,由于避免了在堆内存和堆外内存来回拷贝数据。

PS: 直接内存不受Java堆大小的限制,可是既然是内存确定仍是会受本机总内存的影响

相关文章
相关标签/搜索