JAVA虚拟机之运行时数据区域详解
最近工作不是很忙,所以一直在看深入理解JAVA虚拟机这本书(JVM高级特性与最佳实践,作者:周志明),我个人觉得这本书写的非常的好,几乎覆盖了整个JVM的介绍。所以推荐大家有空的时候去多看一看。虽然我们在平时的工作中可能不会太关注JAVA程序在JVM中是如何运行的。但是如果要成为一个优秀的java开发者,那么学习JVM就非常必要了。这样有助于我们写好代码,出现问题能快速精准的定位分析问题。下面我就针对JVM中的运行时数据区域部分解释。
Java虚拟机在执行java程序的过程中会把它所管理的内存进行划分成若干个不同的数据区域。这些区域都有各自的生命周期,有的区域随着虚拟机的启动而存在,有的区域则依赖用户程序操作而启动和销毁。Java虚拟机管理的内存模型如下图:

一、 程序计数器(Program Counter Register)
程序计数器是内存中很小的一块空间,由于java虚拟机的多线程是通过线程切换并分配处理器执行时间的方式来实现的在任何一个确定时刻,一个处理器都只会执行一条线程中的指令。所以为了线程切换后能恢复正确的执行位置,每条线程都需要有一个独立的程序计数器,个线程之前计数器互相不影响,因此程序计数器区域为“线程私有”内存。
二、 栈(stack)
栈分为java虚拟机栈(java virtual machine stacks)与本地方法栈(native method stack)其实他们的作用都差不多,我这里就它们统称为栈(stack)。栈与程序计数器差不多,也是线程私有的,他们的生命周期与线程相同。
Java虚拟机栈:它java方法执行的内存模型,每个方法执行的同时都会创建一个栈帧用于存放局部变量表、操作数栈、动态链接、方法出口等。每个方法调用直至执行完成的过程,就对应着一个栈帧在虚拟机中入栈到出栈的过程。其实java虚拟机栈就是局部变量表的部分,局部变量表存放了编译期可知的各种基本数据类型,如:boolean、byte、char、short、int、float、long、double、对象的引用(类似于指针)。
本地方法栈:本地方法栈是与java虚拟机栈其实差不多,只是本地方法栈是调用非java语言的方法和数据结构。
三、 堆(Heap)
堆是内存中最大的一块区域并且被线程共享,在虚拟机启动的时候就创建。堆中的作用是存放对象的实例与数组。因此我们程序写的好坏,其实就是看对堆内存是否了解。同时GC(垃圾收集器)也是对的堆内存进行管理。
四、 方法区(Method Area)
方法区与堆内存一样,也是线程共享的一块内存区域,它主要存储虚拟机加载的类信息、常量、静态变量、编译器编译的代码数据。
运行时常量池是属于方法区的一部分,用于存放编译期生成的各种字面量和符号引用,这部分内容将在类加载后进入方法区的运行时常量池存放,当常量池无法在生气到内存的时候会抛存储OutOfMemoryError异常。
本节主要介绍了java虚拟机的内存模型中个区域的作用与功能,希望对大家有帮助。写的不好的地方希望提出来。内存中对象的创建、布局、访问定位我在下一节中做详情的介绍。
文章作者介绍:
来自于小豹科技的李维-公司专注于软件基础研发平台,目前公司正在研发一款基于Netty的插件式的API网关-小豹API网关。 希望与对OpenAPI、微服务、API网关、Service Mesh等感兴趣的朋友多交流。 有兴趣的朋友请加QQ群244054462。

浙公网安备 33010602011771号