Java虚拟机会在在执行Java程序的时候会把其内存划分为一些不同的区域,这些区域都有其各自的用途,并且永远其自己的生命周期,下面我们来看看这张图
由上图我们可以看出,虚拟机的内存区域可以按照是否是线程共享的分为两大块,线程共享的区域有方法区和堆,线程私有的分为虚拟机栈,本地方法栈和程序计数器。下面我们来详细看看这些东西里面都存着什么吧。
方法区
方法区和Java堆一样,同属于是线程共享的数据区域。
方法区用来存储一些已经被虚拟机加载的类型信息、常量、静态变量、即时编译后的代码缓存等数据。
其中方法区还有一个重要的概念,有人称之为“运行时常量池”,当有人提起常量池我们要知道他是方法区的一部分。
堆
堆,我们也通常叫做Java堆,Java堆是虚拟机管理的内存中占用最大的一块,上文提到,他也是线程共享的数据区域,会在虚拟机启动时创建。
Java堆这片内存区域的唯一目的就是用来存放对象的实例的,可以说Java绝大多数的对象都是存放在堆中的,由于会存在逃逸分析、栈上分配、标量替换等因素导致不在堆中分配,这个感兴趣的话可以去扩展一下。
java堆是垃圾收集器管理的内存区域,有人称作其为GC堆(Garbage Collected Heap)也可以翻译成“垃圾堆”,都没毛病,从回收内存的角度看,由于现代垃圾收集器大部分都是基于分
代收集理论设计的,所以Java堆中经常会出现“新生代”“老年代”“永久代”“Eden空间”“From Survivor空
间”“To Survivor空间”等名词。
虚拟机栈
虚拟机栈,也叫做Java虚拟机栈,他是线程私有的,他的生命周期与线程是相同的。虚拟机栈描述的是Java方法在执行的时候的线程内存模型,当每个方法被执行的时候,Java虚拟机都会同步的创建一个栈帧,用于存储局部变量表、操作数栈、动态链接、方法出口等信息。每一个方法被调用直到方法执行完毕的整个过程,就会对应一个栈帧从虚拟机栈入栈到出栈的过程。
本地方法栈
本地方法栈(Native Method Stacks)与虚拟机栈的作用十分相似,区别就是虚拟机栈执行的是Java的方法,而这个本地方法栈所执行的都是本地的方法,本地的方法也就是我们常见的Native的方法。自然,他也是线程独有的。
程序计数器
程序计数器是一块相对较小的内存空间,它可以看作是当前线程执行字节码操作时的行号指示器,在Java虚拟机的模型概念中,字节码指示器的作用就是通过改变这个计数器的值来选取下一条需要执行的字节码指令,它是程序控制流的指示器,分支、循环、跳转、异常处理、线程恢复等一些基础功能都是需要依赖这个程序计数器来完成的。当然,它和前两者一样都是线程独有的。
以上就是关于我们常用的Java虚拟机的内部构成,如有大家还对这方面的知识有什么不理解的地方,欢迎关注我的微信公众号,我们来一起讨论。