JVM内存区域入门

JVM运行时数据区域

Java虚拟机在执行Java程序的过程中,会把它所管理的内存划分为若干个不同的数据区。这些区域有各自的用途,以及创建和销毁的时间,有的区域随着虚拟机进程的启动而存在,有的区域则根据用户线程的启动和结束而建立和销毁,我们可以将这些区域统称为Java运行时数据区域

Java虚拟机运行时数据区域被分为五个区域:堆(Heap)栈(Stack)本地方法栈(Native Stack)方法区(Method Area)程序计数器(Program Count Register)

内存模型的关系图:

这里写图片描述

堆(Java Heap)

对于大多数应用来说,Java Heap是Java虚拟机管理的内存的最大一块,这块区域随着虚拟机的启动而创建。在实际的运用中,我们创建的对象和数组就是存放在堆里面。Java Heap是一块共享的区域,操作共享区域的成员就有了锁和同步,因此就有线程安全问题

与Java Heap相关的还有Java的垃圾回收机制(GC),Java Heap是垃圾回收器管理的主要区域。程序猿所熟悉的新生代、老生代、永久代的概念就是在堆里面,现在大多数的GC基本都采用了分代收集算法,分代收集算法将堆内存分为多个部分分别用不同的方法进行垃圾回收,新生代还可以分为Eden空间,From Survivor空间,To Survivor空间

Java Heap可以处于物理上不连续的内存空间中,只要逻辑上是连续的即可

这里写图片描述

栈(Java Stack)

相对于Java Heap来讲,Java Stack是线程私有的,它的生命周期与线程相同。Java Stack描述的是Java方法执行时的内存模型,每个方法执行时都会创建一个栈帧(Stack Frame)用语存储局部变量表、操作数栈、动态链接、方法出口等信息

每个线程在执行一个方法时,都有一个栈帧在当前线程对应的栈帧中入栈和出栈,每一个栈帧中都有局部变量表。局部变量表存放了编译期间的各种基本数据类型,对象引用等信息。
这里写图片描述

本地方法栈(Native Stack)

本地方法栈(Native Stack)与Java虚拟机栈(Java Stack)所发挥的作用非常相似,他们之间的区别在于虚拟机栈为虚拟机栈执行java方法(也就是字节码)服务,而本地方法栈则为使用到Native方法服务

方法区(Method Area)

方法区(Method Area)与堆(Java Heap)一样,是各个线程共享的内存区域,它用于存储虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码等数据。虽然Java虚拟机规范把方法区描述为堆的一个逻辑部分,但是它却有一个别名叫做非堆(Non-Heap)

分析下Java虚拟机规范,之所以把方法区描述为堆的一个逻辑部分,应该觉得它们都是存储数据的角度出发的。一个存储对象数据(堆),一个存储静态信息(方法区)

在上文中,我们看到堆中有新生代、老生代、永久代的描述。为什么我们将新生代、老生代、永久代三个概念一起说,那是因为HotSpot虚拟机的设计团队选择把GC分代收集扩展至方法区,或者说使用永久代来实现方法区而已。这样HotSpot的垃圾收集器就能想管理Java堆一样管理这部分内存。简单点说就是HotSpot虚拟机中内存模型的分代,其中新生代和老生代在堆中,永久代使用方法区实现。根据官方发布的路线图信息,现在也有放弃永久代并逐步采用Native Memory来实现方法区的规划,在JDK1.7的HotSpot中,已经把原本放在永久代的字符串常量池移出。

猜你喜欢

转载自blog.csdn.net/eagleuniversityeye/article/details/80175214
今日推荐