(1) JVM系列--内存区域

(1) JVM系列--内存区域_第1张图片

一. JVM运行时数据区

java 虚拟机在执行java程序的时候,会将内存划分为若干个不同的区域,都各自有自己的用途,下图是java 虚拟机运行时数据区图:

(1) JVM系列--内存区域_第2张图片
java虚拟机运行时数据区.jpg

1 方法区

该区主要用来存储已被虚拟机加载的类信息,常量,静态变量,以及JIT编译完之后的代码等,很多人将方法区称为"永久代",其实两者是不等价的,仅仅是将GC分代收集扩展到方法区,这样hotSpot 的垃圾回收器就可以像管理java堆一样管理这部分内存,对于JRocket,J9,是没有这个概念的。

2 虚拟机栈

线程私有的,生命周期和线程一样,描述了java 方法执行的内存模型,用栈帧来存储局部变量表,操作数栈,动态链接,方法出口,方法执行对应了进栈和出栈,这边规定了StackOverflowError : 线程所请求的栈深度大于虚拟机所允许的深度,以及由于支持动态拓展之后出现的无法申请到足够的内存而抛出的OutOfMemoryError.

3 本地方法栈

虚拟机使用的Native方法服务,与虚拟机栈类似,也会抛StackoverflowError以及OutOfMemoryError.

4 java堆

虚拟机管理的内存中最大的一块,是所有线程共享的一块区域,"几乎"所有的对象实例都是在这里分配内存,随着JIT的发展与逃逸分析技术成熟,栈上分配,标量替换等使得对象的分配都在堆上面变得不是那么绝对。这一块也是GC回收器管理的主要区域,java堆空间可划分为:新生代和老年代,再细分就是,新生代里面可以又划分为:Eden区,From Survivior,To Survivor. 这边还有一个是TLAB(Thread Local Allocation Buffer), 在堆中创建出来的多个线程私有的分配缓冲区。

5 程序计数器

当前线程执行的字节码的行号指示器,各个线程之间都独立存储私有这一块内存区域,注意当执行的Native方法时,该计数器为空,也是唯一一个在java 虚拟机规范中没有规定任何的OutOfMemoryError的区域。

二. 非JVM运行时数据区

1 直接内存

并不是虚拟机运行时数据区的一部分,也不是java虚拟机规范中定义的内存区域,java 通过在堆中的DirectByteBuffer 对象作为这块内存的引用进行操作。

你可能感兴趣的:((1) JVM系列--内存区域)