JVM系列之一 JVM的基础概念与内存区域
前言
作为一名 Java 语言的使用者,学习 JVM 有助于解决程序运行过程中出现的问题、写出性能更高的代码。
可以说:学好 JVM 是成为中高级 Java 工程师的必经之路。
有感于从未整理归纳 JVM 相关的知识,所以打算写一系列 JVM 相关的文章,以加深巩固习得成果,为后续遗忘提供快速找回之途径。
一、JVM 是什么?
Java 虚拟机 (简称JVM,Java Virtual Machine) ,是运行 Java 程序的平台,准确来说,是运行字节码的平台。
Java 为达成
Write Once, Run Everywhere
的目标,对于不同操作系统有不同的虚拟机实现,使用class 字节码作为中间码,JVM 执行字节码完成程序功能。
二、JVM的内存区域
1、程序计数器
程序计数器(Program Counter Register)是一小块线程私有的内存区域,生命周期与线程相同,可看作是当前线程执行字节码的行号指示器。是 JVM 中唯一一个不会出现 OOM(OutOfMemeryError)的区域。
如果线程执行的是一个 Java 方法,计数器记录的是正在执行的虚拟机字节码指令的地址;
如果执行的是一个 Native 方法,则计数器值为空。
2、虚拟机栈
虚拟机栈(Virtual Machine Stack)是线程私有的内存区域,生命周期与线程相同,描述着Java方法执行的内存模型:每个方法在执行时都会创建一个栈帧(Stack Frame)用于存储局部变量表、操作数栈、动态链接、方法出口等信息。每个方法执行完成就对应着销毁这个栈帧,即出栈。
此区域只会出现两种异常:
- StackOverflowError:当申请的栈深度达到 JVM 允许的最大深度时抛出。
- OutOfMemeryError:如果虚拟机栈可动态扩展,但申请不到足够内存时抛出。
3、本地方法栈
本地方法栈(Native Method Stack)与虚拟机栈作用类似,也是线程私有的内存区域,区别在于运行的是本地方法(Native Method)。
本地方法,即非Java语言实现的方法,比如C,使用本地方法可以扩充Java没有的语言特性。
4、堆
堆(Heap)是线程共享的内存区域,是JVM管理中最大的内存区域,唯一作用就是存放对象实例,是 JVM 垃圾收集的主要区域。
5、方法区
方法区(Method Area)又名非堆(Non-Heap)是线程共享的内存区域,存储着被 JVM 加载的类信息、常量、静态变量、即时编译器编译后的二进制等数据。
6、运行时常量池
运行时常量池(Runtime Constant Pool)是方法区的一部分,用于存放编译期生成的字面量和符号引用,这部分内容将在类加载后进入方法区运行时常量池中存放。
7、直接内存
直接内存(Direct Memery)即通过native方法直接分配在堆外的内存。它不是JVM虚拟机运行时数据区的一部分,也不在JVM规范中定义,但这部分内存使用频繁,也可能导致OOM。
总结
JVM 是一个运行着字节码的平台,其运行时数据区包含 程序计数器、虚拟机方法栈、本地方法栈、堆、方法区,前三者是线程私有(隔离)的,后两者是线程共享的。
以上就是JVM的基本概念与其运行时数据区内存的内容。
参考
- 《深入理解Java虚拟机 第2版》周志明著
本文同步发布于本人csdn